Skip to content

feat: Static URL Support for Applications and Pages#41312

Merged
ashit-rath merged 27 commits intoreleasefrom
chore/static-ce
Oct 30, 2025
Merged

feat: Static URL Support for Applications and Pages#41312
ashit-rath merged 27 commits intoreleasefrom
chore/static-ce

Conversation

@ashit-rath
Copy link
Contributor

@ashit-rath ashit-rath commented Oct 22, 2025

🎯 Overview

This PR implements Static URL functionality for Appsmith applications and pages, allowing users to create clean, URLs without auto-generated IDs. This feature is gated behind the release_static_url_enabled feature flag.

🚀 Key Features

1. Application-Level Static URLs

  • Enable/Disable Static URLs: Toggle static URLs on/off at the application level
  • Custom Application Slug: Set a unique, human-readable slug for the entire application (e.g., my-app instead of untitled-application-5)
  • Real-time Validation: Client-side and server-side validation for slug format (lowercase letters, numbers, hyphens only)
  • Availability Check: Real-time checking if a slug is available or already taken
  • Slug Suggestions: Auto-generate slug suggestions based on application name

2. Page-Level Static URLs

  • Custom Page Slugs: Set unique slugs for individual pages (e.g., dashboard instead of page1-68fb0a086001f8101c93e34q)
  • Per-Page Configuration: Each page can have its own static slug
  • Validation & Uniqueness: Real-time validation and uniqueness checking for page slugs

3. URL Format Changes

Before (Legacy Format):

/app/application-slug/page-name-<pageId>

After (Static URL Format):

/app/app-slug/page-slug

🏗️ Technical Implementation

New Routes

  • BUILDER_PATH_STATIC: /app/:staticApplicationSlug/:staticPageSlug/edit
  • VIEWER_PATH_STATIC: /app/:staticApplicationSlug/:staticPageSlug

New Redux Actions

  • ENABLE_STATIC_URL / DISABLE_STATIC_URL: Toggle static URL feature
  • PERSIST_APP_SLUG / PERSIST_PAGE_SLUG: Save application/page slugs
  • VALIDATE_APP_SLUG / VALIDATE_PAGE_SLUG: Validate slug availability
  • FETCH_APP_SLUG_SUGGESTION: Get auto-generated suggestions

New API Endpoints

Application APIs

  • POST /api/v1/applications/:applicationId/static-url - Enable static URL with initial slug
  • PUT /api/v1/applications/:applicationId/static-url - Update application slug
  • DELETE /api/v1/applications/:applicationId/static-url - Disable static URL
  • GET /api/v1/applications/:applicationId/static-url/:uniqueSlug - Validate application slug availability
  • GET /api/v1/applications/:applicationId/static-url/suggest-app-slug - Get slug suggestion

Page APIs

  • PATCH /api/v1/pages/static-url - Update page slug
  • GET /api/v1/pages/:pageId/static-url/verify/:uniqueSlug - Validate page slug availability

URL Assembly Enhancements

  • Extended URLAssembly to support static URL generation
  • Added URL_TYPE.STATIC for static URL routing
  • Static URLs only apply in published/viewer mode (edit mode uses regular URLs)
  • Automatic fallback: If staticPageSlug is not set, falls back to regular pageSlug

🎨 UI Components

General Settings (Application Level)

  • Static URL Toggle: Enable/disable static URLs for the application
  • Application Slug Input:
    • Real-time validation with error messages
    • Loading states during validation
    • Success/error indicators
    • URL preview showing the final URL
  • Apply/Cancel Buttons: Persist or discard changes
  • Confirmation Modal: Shows before/after URLs when changing or disabling

Page Settings (Page Level)

  • Page Slug Input: Similar to application slug with validation
  • URL Preview: Shows the complete page URL
  • Apply/Cancel Actions: Per-page slug management

StaticURLConfirmationModal

  • Displays "From" and "To" URLs
  • Warning message about breaking existing links
  • Different modes: "Change" vs "Disable"
  • Bold formatting for app/page slugs in URLs

🔄 State Management

Application Reducer

  • uniqueSlug: Stores the application's static slug
  • staticUrlEnabled: Boolean flag for static URL status

Page List Reducer

  • uniqueSlug: Stores each page's static slug
  • Updates only the specific page when slug is persisted

Applications UI Reducer

  • isValidatingAppSlug: Validation in progress
  • isApplicationSlugValid: Validation result
  • isFetchingAppSlugSuggestion: Fetching suggestion
  • appSlugSuggestion: Auto-generated suggestion
  • isPersistingAppSlug: Save in progress

🛡️ Validation Rules

Application/Page Slug Requirements:

  • Only lowercase letters (a-z)
  • Numbers (0-9)
  • Hyphens (-)
  • No spaces or special characters
  • Must be unique across the workspace
  • Cannot be empty

🔀 Navigation & Routing

Route Matching Updates

  • Extended matchBuilderPath to include BUILDER_PATH_STATIC
  • Extended matchViewerPath to include VIEWER_PATH_STATIC
  • Updated route params to include optional staticApplicationSlug and staticPageSlug

Page Navigation

  • New hook: useStaticUrlGeneration for generating static URLs in navigation
  • Updated useNavigateToAnotherPage to support static URLs
  • Menu items and navigation components updated to use static URLs when available

📦 Key Files Changed

Core Logic:

  • URLAssembly.ts: URL generation logic with static URL support
  • ApplicationSagas.tsx: Sagas for enable/disable/persist operations
  • PageSagas.tsx: Page-level slug persistence
  • appRoutes.ts: New static URL routes

UI Components:

  • GeneralSettings.tsx: Application-level static URL configuration
  • PageSettings.tsx: Page-level static URL configuration
  • StaticURLConfirmationModal.tsx: Confirmation dialog (new)
  • UrlPreview.tsx: URL preview component (new)

State Management:

  • applicationsReducer.tsx: Application UI state
  • appReducer.ts: Application entity state
  • pageListReducer.tsx: Page list state

⚙️ Feature Flag

  • release_static_url_enabled: Controls visibility of static URL features

Automation

/ok-to-test tags="@tag.All"

🔍 Cypress test results

Tip

🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/18936467359
Commit: a74b4ac
Cypress dashboard.
Tags: @tag.All
Spec:


Thu, 30 Oct 2025 10:56:15 UTC

Communication

Should the DevRel and Marketing teams inform users about this change?

  • Yes
  • No

Summary by CodeRabbit

  • New Features

    • Static URL support for apps and pages: enable/disable static URLs, edit app/page slugs, validate and persist slugs, and receive slug suggestions.
    • URL preview with click-to-copy and a confirmation modal when changing or disabling app slugs.
  • Bug Fixes / Improvements

    • Routing, editor and viewer flows updated for slug-based paths.
    • Base page resolution and editor links now derive from application state for more reliable navigation and loading.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 22, 2025

Walkthrough

Added static URL (slug) support across routing, URL assembly, APIs, Redux (actions/reducers/sagas/selectors), and UI; propagated staticApplicationSlug/staticPageSlug through init and middleware flows. Multiple components now derive basePageId from getCurrentBasePageId selector instead of route params.

Changes

Cohort / File(s) Summary
Static Route Constants & Routing
app/client/src/ce/IDE/constants/routes.ts, app/client/src/ce/constants/routes/appRoutes.ts, app/client/src/ce/AppRouter.tsx, app/client/src/ce/pages/common/AppHeader.tsx, app/client/src/pages/AppIDE/layout/routers/MainPane/constants.ts, app/client/src/pages/AppIDE/layouts/routers/RightPane.tsx, app/client/src/pages/AppIDE/layouts/routers/UISegmentLeftPane/UISegmentLeftPane.tsx, app/client/src/pages/AppIDE/layouts/components/Explorer.tsx, app/client/src/utils/helpers.tsx
Added BUILDER_PATH_STATIC and VIEWER_PATH_STATIC; integrated static routes into matchers, path-splitting, route lists and helper routing logic.
URL Assembly & Params
app/client/src/ce/entities/URLRedirect/URLAssembly.ts, app/client/src/ce/middlewares/RouteParamsMiddleware.ts, app/client/src/sagas/InitSagas.ts
Added URL_TYPE.STATIC, staticApplicationSlug/staticPageSlug to params/registry, updated URL type resolution & formatting, propagated static slugs through init and middleware.
API Layer
app/client/src/ce/api/ApplicationApi.tsx, app/client/src/api/PageApi.tsx, app/client/src/api/services/ConsolidatedPageLoadApi/types.ts
New endpoints for persisting/validating/enabling/disabling app/page slugs; added uniqueSlug/optional static slug fields and extended consolidated API params.
Redux Actions & Constants
app/client/src/ce/actions/applicationActions.ts, app/client/src/actions/pageActions.tsx, app/client/src/ce/constants/ReduxActionConstants.tsx
Added action creators and Redux action type constants for app- and page-slug flows (persist, validate, suggest, enable/disable, reset) and associated error types.
Sagas (CE & EE)
app/client/src/ce/sagas/ApplicationSagas.tsx, app/client/src/ce/sagas/PageSagas.tsx, app/client/src/ee/sagas/ApplicationSagas.tsx, app/client/src/ee/sagas/PageSagas.tsx
Implemented saga handlers for persist/validate/enable/disable/fetch-suggestion; wired debounced validation and watchers; adjusted publish/init flow to await fetch before URL generation.
Reducers & State
app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx, app/client/src/reducers/entityReducers/appReducer.ts, app/client/src/reducers/entityReducers/pageListReducer.tsx, app/client/src/reducers/uiReducers/appSettingsPaneReducer.tsx
Added app-level slug state (persisting/validating/validity/suggestion) and per-page slug persistence/validation state; reducers updated to handle new actions and persist uniqueSlug on pages.
Selectors
app/client/src/ce/selectors/applicationSelectors.tsx, app/client/src/selectors/editorSelectors.tsx
Added selectors for app slug state (getIsPersistingAppSlug, getIsApplicationSlugValid, etc.) and editor selectors (getBasePageIdFromStaticSlug, getIsStaticUrlEnabled, per-page slug flags).
Entities & Types
app/client/src/entities/Application/types.ts, app/client/src/entities/Page/types.ts, app/client/src/entities/Engine/index.ts, app/client/src/actions/initActions.ts, app/client/src/ce/constants/routes/appRoutes.ts, app/client/src/pages/AppIDE/Explorer/helpers.tsx
Added staticUrlSettings and uniqueSlug on entities; introduced staticApplicationSlug/staticPageSlug in payloads/types; made many basePageId params optional and extended route param typings.
App Settings UI & Utilities
app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx, app/client/src/pages/AppIDE/components/AppSettings/components/PageSettings.tsx, app/client/src/pages/AppIDE/components/AppSettings/components/StaticURLConfirmationModal.tsx, app/client/src/pages/AppIDE/components/AppSettings/components/UrlPreview.tsx, app/client/src/pages/AppIDE/components/AppSettings/utils.ts, app/client/src/pages/AppIDE/components/AppSettings/types.ts, app/client/src/pages/AppIDE/components/AppSettings/AppSettings.tsx
Added Static URL UI (toggle, slug input, preview, confirmation modal), slug normalization/validation and suggestion flows, moved AppSettingsTabs to types.ts, and extended URL preview utilities for static slugs.
Editor / Viewer Loaders & Pages
app/client/src/pages/AppIDE/AppIDE.tsx, app/client/src/pages/AppIDE/AppIDELoader.tsx, app/client/src/pages/AppViewer/index.tsx, app/client/src/pages/AppViewer/loader.tsx, app/client/src/pages/AppViewer/AppViewerPageContainer.tsx
Init payloads accept and propagate static slugs; basePageId resolution augmented to resolve from staticPageSlug when missing; viewer/editor init flows updated to use resolved basePageId and static slugs.
Navigation & Active-State
app/client/src/pages/AppViewer/Navigation/components/MenuItem/index.tsx, app/client/src/pages/AppViewer/Navigation/components/MoreDropDownButtonItem.tsx, app/client/src/pages/AppViewer/Navigation/components/MenuItem/MenuItem.test.tsx, app/client/src/pages/AppViewer/PrimaryCTA.test.tsx
Active-state logic extended to consider uniqueSlug for static routes; tests updated to cover static-slug active detection; test fixtures extended.
Base Page ID Derivation (selector switch)
app/client/src/PluginActionEditor/components/PluginActionResponse/components/BindDataButton.tsx, app/client/src/components/editorComponents/GlobalSearch/index.tsx, app/client/src/pages/Editor/DataSourceEditor/index.tsx, app/client/src/pages/Editor/SaaSEditor/DatasourceForm.tsx, app/client/src/pages/AppViewer/AppViewerPageContainer.tsx
Replaced route-param-derived basePageId with selector-derived getCurrentBasePageId (via useSelector) in multiple components; payloads and internal usage updated accordingly.
Feature Flag & Messages
app/client/src/ce/entities/FeatureFlag.ts, app/client/src/ce/constants/messages.ts
Added release_static_url_enabled feature flag (default false) and new slug-related UI message constants.
Misc / Tests / Imports
app/client/src/ce/entities/IDE/utils/getEditableTabPermissions.ts, app/client/src/pages/AppIDE/layouts/components/Explorer.tsx, app/client/src/sagas/__tests__/initSagas.test.ts, app/client/src/selectors/appSettingsPaneSelectors.tsx, app/client/src/pages/AppIDE/components/AppSettings/components/LayoutSystemBasedPageViewer.tsx, app/client/src/utils/helpers.tsx
Minor import updates, inclusion of static path constants in route lists, and test updates for init sagas and static routes.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UI as "App Settings UI"
    participant Redux
    participant Saga
    participant API
    participant State

    User->>UI: Type app slug
    UI->>Redux: dispatch VALIDATE_APP_SLUG
    Redux->>Saga: validateAppSlugSaga (debounced)
    Saga->>API: validateAppSlug(slug)
    API-->>Saga: { isUniqueSlugAvailable }
    Saga->>Redux: VALIDATE_APP_SLUG_SUCCESS / VALIDATE_APP_SLUG_ERROR
    Redux->>State: update validity flags
    State-->>UI: show availability

    User->>UI: Confirm change
    UI->>Redux: dispatch ENABLE_STATIC_URL / PERSIST_APP_SLUG
    Redux->>Saga: enableStaticUrlSaga / persistAppSlugSaga
    Saga->>API: enable/persist endpoints
    API-->>Saga: success
    Saga->>Redux: ENABLE_STATIC_URL_SUCCESS / PERSIST_APP_SLUG_SUCCESS
    Redux->>State: update app/page slug and routing type
Loading
sequenceDiagram
    participant Browser
    participant Router
    participant Redux
    participant Engine

    Browser->>Router: GET /app/:staticApplicationSlug/:pageSlug
    Router->>Redux: extract staticApplicationSlug, staticPageSlug
    Router->>Engine: dispatch initAppViewerAction(staticApplicationSlug, staticPageSlug)
    Engine->>Redux: selector getBasePageIdFromStaticSlug(staticPageSlug)
    Redux-->>Engine: basePageId (matched by page.uniqueSlug)
    Engine->>Engine: loadAppData(basePageId)
    Engine-->>Browser: render resolved page
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Key areas needing extra attention:

  • app/client/src/ce/entities/URLRedirect/URLAssembly.ts — new STATIC type, formatting and backward compatibility across modes.
  • app/client/src/sagas/InitSagas.ts — consolidated init flow, START/END_CONSOLIDATED_PAGE_LOAD ordering, and new params propagation.
  • app/client/src/pages/AppIDE/* and app/client/src/pages/AppViewer/* — resolving basePageId from static slug, effect dependencies and race conditions.
  • app/client/src/pages/AppIDE/components/AppSettings/* — slug normalization, debounced validation, modal flows and feature-flag gating.
  • app/client/src/ce/middlewares/RouteParamsMiddleware.ts & app/client/src/ce/entities/URLRedirect/SlugURLRedirect.ts — ensure static slugs populate consistently across action flows.
  • app/client/src/selectors/editorSelectors.tsx — duplicated selector blocks detected; consolidate to avoid export conflicts.
  • BindDataButton and other components switched to getCurrentBasePageId — verify no regressions from replacing route param usage.

Poem

✨ A slug finds home where IDs once stood,
Routes grow friendlier, paths understood.
Validation hums, the modal nods,
Pages resolve on gentler odds.
Cheers to slugs and smoother roads!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.14% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description Check ❓ Inconclusive The pull request description is comprehensive and well-organized with clear sections covering overview, key features, technical implementation, UI components, state management, and testing results. However, it is missing several required elements from the description template: specifically, the "Fixes #Issue Number" or issue URL reference (a required field), a dependencies section, and links to relevant external documents (Notion, Figma, etc.) as specified in the template. While the description is detailed and substantive, the template explicitly calls for these structural elements to be present in all PRs. Add the missing required template sections: include a "Fixes #Issue Number" or "Fixes Issue URL" line at the top to reference the related issue; add a dependencies section if any external dependencies exist for this feature; and include links to any relevant design documents, specifications, or tracking pages (e.g., Notion, Figma, Jira) that informed this implementation. Additionally, consider adding a TL;DR section since this description is quite lengthy and technical, as suggested in the template guidance.
✅ Passed checks (1 passed)
Check name Status Explanation
Title Check ✅ Passed The PR title "feat: Static URL Support for Applications and Pages" is directly related to the main changes in the changeset, which implements static URL functionality for both application and page-level features. The title is concise, uses conventional commit format, and clearly communicates the primary feature without unnecessary noise or vagueness. It accurately summarizes what developers scanning the history would expect to find: comprehensive static URL support across the system.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/static-ce

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added the skip-changelog Adding this label to a PR prevents it from being listed in the changelog label Oct 22, 2025
@github-actions
Copy link

🔴🔴🔴 Cyclic Dependency Check:

This PR has increased the number of cyclic dependencies by 2, when compared with the release branch.

Refer this document to identify the cyclic dependencies introduced by this PR.

You can view the dependency diff in the run log. Look for the check-cyclic-dependencies job in the run.

@github-actions
Copy link

🔴🔴🔴 Cyclic Dependency Check:

This PR has increased the number of cyclic dependencies by 2, when compared with the release branch.

Refer this document to identify the cyclic dependencies introduced by this PR.

You can view the dependency diff in the run log. Look for the check-cyclic-dependencies job in the run.

@ashit-rath ashit-rath added ok-to-test Required label for CI and removed ok-to-test Required label for CI labels Oct 27, 2025
@ashit-rath ashit-rath changed the title chore: Static URL feat: Static URL Support for Applications and Pages Oct 27, 2025
@github-actions github-actions bot added Enhancement New feature or request and removed skip-changelog Adding this label to a PR prevents it from being listed in the changelog labels Oct 27, 2025
@ashit-rath ashit-rath removed the ok-to-test Required label for CI label Oct 27, 2025
@ashit-rath ashit-rath added the ok-to-test Required label for CI label Oct 27, 2025
@github-actions
Copy link

Deploy-Preview-URL: https://ce-41312.dp.appsmith.com

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (5)
app/client/src/ce/constants/messages.ts (1)

1919-1933: Align wording with “slug” and improve placeholder/empty text.

Use a slug-focused placeholder and explicit empty error:

-export const GENERAL_SETTINGS_APP_URL_PLACEHOLDER = () => "app-url";
+export const GENERAL_SETTINGS_APP_URL_PLACEHOLDER = () => "app-slug";
@@
-export const GENERAL_SETTINGS_APP_URL_EMPTY_VALUE_MESSAGE = () =>
-  "Enter a value";
+export const GENERAL_SETTINGS_APP_URL_EMPTY_VALUE_MESSAGE = () =>
+  "App slug cannot be empty";
app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx (1)

779-788: Default to false on VALIDATE_APP_SLUG_ERROR.

Defensive default avoids inconsistent state if payload is malformed:

- isApplicationSlugValid: action.payload.isValid,
+ isApplicationSlugValid: false,
app/client/src/pages/AppIDE/components/AppSettings/components/PageSettings.tsx (2)

387-402: Normalize slugs to lowercase at the shared helper to avoid case-only collisions.

Current flow allows uppercase; spec is lowercase/0-9/hyphen. Fix once in filterAccentedAndSpecialCharacters and drop local workarounds. Also ensures reserved-pattern checks (ObjectId/UUID) aren’t bypassed by uppercase.

Apply in utils (single source of truth), then keep this file unchanged:

diff --git a/app/client/src/pages/AppIDE/components/AppSettings/utils.ts b/app/client/src/pages/AppIDE/components/AppSettings/utils.ts
@@
 export const filterAccentedAndSpecialCharacters = (value: string) => {
   return decodeURI(value)
     .replaceAll(" ", "-")
-    .replaceAll(/[^A-Za-z0-9-]/g, "");
+    .replaceAll(/[^A-Za-z0-9-]/g, "")
+    .toLowerCase();
 };

This will also make checkPageNameSlugConflict comparisons robust.

Also applies to: 330-359, 58-62


540-542: Fix CSS class typo (extra parenthesis).

- <strong className="text-[color:var(--appsmith-color-black-800))]">
+ <strong className="text-[color:var(--appsmith-color-black-800)]">
app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx (1)

292-295: Fix CSS class typo (extra parenthesis).

- <strong className="text-[color:var(--appsmith-color-black-800))]">
+ <strong className="text-[color:var(--appsmith-color-black-800)]">
🧹 Nitpick comments (12)
app/client/src/pages/AppIDE/components/AppSettings/components/PageSettings.tsx (6)

295-314: Guard save while validation is in-flight to avoid persisting a stale slug.

If the user hits Enter before availability result returns, you may persist an unverified slug. Add a simple guard:

 const saveStaticPageSlug = useCallback(() => {
-  if (!canManagePages || page.uniqueSlug === staticPageSlug) return;
+  if (!canManagePages || page.uniqueSlug === staticPageSlug) return;
+  // Wait for validation to complete
+  if (isValidatingPageSlug) return;
   // Don't save if there's a validation error
   if (staticPageSlugError) return;
   // Don't save if the page slug is not valid
   if (!isPageSlugValid) return;
   dispatch(persistPageSlug(page.pageId, staticPageSlug || ""));
-}, [
+}, [
   page.pageId,
   page.uniqueSlug,
   staticPageSlug,
   canManagePages,
   dispatch,
   staticPageSlugError,
-  isPageSlugValid,
+  isPageSlugValid,
+  isValidatingPageSlug,
 ]);

Optionally track “lastValidatedSlug” in state to ensure it matches the current input before saving.


387-399: Debounce availability checks to reduce chatty API calls.

Wrap validatePageSlug in a debounced callback (e.g., 300–500 ms) to avoid 1 req/keystroke:

+import { debounce } from "lodash";
@@
-  const onStaticPageSlugChange = (value: string) => {
+  const debouncedValidate = useMemo(
+    () => debounce((slug: string) => dispatch(validatePageSlug(page.pageId, slug)), 400),
+    [dispatch, page.pageId],
+  );
+  const onStaticPageSlugChange = (value: string) => {
     const normalizedValue =
       value.length > 0 ? filterAccentedAndSpecialCharacters(value) : value;
@@
-    if (!errorMessage && normalizedValue && normalizedValue.trim().length > 0) {
-      dispatch(validatePageSlug(page.pageId, normalizedValue));
-    }
+    if (!errorMessage && normalizedValue && normalizedValue.trim().length > 0) {
+      debouncedValidate(normalizedValue);
+    }

Remember to cancel on unmount if needed.


522-533: Use origin for copy to include port and avoid mismatch.

String-build misses port; origin is simpler:

- onCopy={async () => {
-   navigator.clipboard.writeText(
-     location.protocol +
-       "//" +
-       window.location.hostname +
-       pathPreview.relativePath,
-   );
- }}
+ onCopy={async () => {
+   navigator.clipboard.writeText(
+     window.location.origin + pathPreview.relativePath,
+   );
+ }}

165-171: Don’t render Icon when no icon is intended.

You set icon: "" for the deploy message but always render . Make icon optional and guard the render:

- return { icon: "" as const, color: "var(--ads-v2-color-fg)", message: ... };
+ return { color: "var(--ads-v2-color-fg)", message: ... };
- <Icon
-   color={pageSlugValidationMessage.color}
-   name={pageSlugValidationMessage.icon}
-   size="sm"
- />
+ {pageSlugValidationMessage.icon && (
+   <Icon
+     color={pageSlugValidationMessage.color}
+     name={pageSlugValidationMessage.icon}
+     size="sm"
+   />
+ )}

Also applies to: 505-517


491-491: Localize label instead of hardcoding “Page slug”.

Add PAGE_SETTINGS_PAGE_SLUG_LABEL to messages.ts and use createMessage here for consistency/i18n.


113-134: Prefer useMemo over useCallback+invoke for computing pathPreview.

You’re creating a function only to call it immediately. Simplify:

- const pathPreview = useCallback(getUrlPreview, [ /* deps */ ])(
-   page.pageId, pageName, page.pageName, currentApplication?.uniqueSlug || "",
-   customSlug, page.customSlug, isStaticUrlEnabled, staticPageSlug, page.uniqueSlug || page.slug,
- );
+ const pathPreview = useMemo(
+   () =>
+     getUrlPreview(
+       page.pageId,
+       pageName,
+       page.pageName,
+       currentApplication?.uniqueSlug || "",
+       customSlug,
+       page.customSlug,
+       isStaticUrlEnabled,
+       staticPageSlug,
+       page.uniqueSlug || page.slug,
+     ),
+   [
+     page.pageId,
+     pageName,
+     page.pageName,
+     currentApplication?.uniqueSlug,
+     customSlug,
+     page.customSlug,
+     isStaticUrlEnabled,
+     staticPageSlug,
+     page.uniqueSlug,
+     page.slug,
+   ],
+ );
app/client/src/ce/sagas/ApplicationSagas.tsx (2)

1347-1391: Include the error object in DISABLE_STATIC_URL_ERROR for better diagnostics.

Currently only message/show are dispatched. Add the error for central handlers/toasts:

-  yield put({
-    type: ReduxActionErrorTypes.DISABLE_STATIC_URL_ERROR,
-    payload: {
-      show: true,
-      message: createMessage(ERROR_IN_DISABLING_STATIC_URL),
-    },
-  });
+  yield put({
+    type: ReduxActionErrorTypes.DISABLE_STATIC_URL_ERROR,
+    payload: {
+      error,
+      show: true,
+      message: createMessage(ERROR_IN_DISABLING_STATIC_URL),
+    },
+  });

204-207: Nit: fix variable name typo.

Rename appicationViewPageUrl → applicationViewPageUrl.

Also applies to: 210-215

app/client/src/ce/constants/messages.ts (1)

1962-1967: Add label for page slug to avoid hardcoded string in UI.

Add and use in PageSettings:

+export const PAGE_SETTINGS_PAGE_SLUG_LABEL = () => "Page slug";
app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx (2)

218-240: Reuse the shared normalizer for consistency with page slugs.

Use filterAccentedAndSpecialCharacters (with the proposed toLowerCase) to keep behavior identical across app/page slug inputs:

-import { APPLICATION_SLUG_REGEX } from ... // keep regex
+import { filterAccentedAndSpecialCharacters } from "../utils";
@@
-  const onSlugChange = useCallback(
-    (value: string) => {
-      // Convert to lowercase and replace spaces with hyphens
-      const normalizedValue = value.toLowerCase().replace(/\s+/g, "-");
+  const onSlugChange = useCallback(
+    (value: string) => {
+      const normalizedValue =
+        value.length > 0 ? filterAccentedAndSpecialCharacters(value) : value;

Keeps a single acceptance surface for characters.


104-106: Initialize toggle from staticUrlEnabled, not just presence of uniqueSlug.

uniqueSlug may exist historically; the feature flag is controlled by staticUrlEnabled.

-const [isStaticUrlToggleEnabled, setIsStaticUrlToggleEnabled] =
-  useState(!!applicationSlug);
+const [isStaticUrlToggleEnabled, setIsStaticUrlToggleEnabled] =
+  useState(!!application?.staticUrlEnabled);
app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx (1)

831-838: Wire up isErrorPersistingAppSlug to reflect failures (or remove the field).

You introduced isErrorPersistingAppSlug but never update it. Either use it:

 [ReduxActionTypes.ENABLE_STATIC_URL_SUCCESS]: (state) => ({
   ...state,
   isPersistingAppSlug: false,
+  isErrorPersistingAppSlug: false,
 }),
 [ReduxActionErrorTypes.ENABLE_STATIC_URL_ERROR]: (state) => ({
   ...state,
   isPersistingAppSlug: false,
+  isErrorPersistingAppSlug: true,
 }),
@@
 [ReduxActionTypes.DISABLE_STATIC_URL_SUCCESS]: (state) => ({
   ...state,
   isPersistingAppSlug: false,
+  isErrorPersistingAppSlug: false,
 }),
 [ReduxActionErrorTypes.DISABLE_STATIC_URL_ERROR]: (state) => ({
   ...state,
   isPersistingAppSlug: false,
+  isErrorPersistingAppSlug: true,
 }),
@@
 [ReduxActionTypes.PERSIST_APP_SLUG_SUCCESS]: (state) => ({
   ...state,
   isPersistingAppSlug: false,
+  isErrorPersistingAppSlug: false,
 }),
 [ReduxActionTypes.PERSIST_APP_SLUG_ERROR]: (state) => ({
   ...state,
   isPersistingAppSlug: false,
+  isErrorPersistingAppSlug: true,
 }),

…or drop the field to avoid dead state.

Also applies to: 853-860, 875-882, 48-53, 915-919

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9f33b21 and 03ec98d.

📒 Files selected for processing (11)
  • app/client/src/ce/constants/messages.ts (1 hunks)
  • app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx (3 hunks)
  • app/client/src/ce/sagas/ApplicationSagas.tsx (4 hunks)
  • app/client/src/ce/selectors/applicationSelectors.tsx (2 hunks)
  • app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx (7 hunks)
  • app/client/src/pages/AppIDE/components/AppSettings/components/PageSettings.tsx (13 hunks)
  • app/client/src/pages/AppViewer/Navigation/components/MenuItem/index.tsx (3 hunks)
  • app/client/src/pages/AppViewer/Navigation/components/TopHeader.tsx (1 hunks)
  • app/client/src/pages/AppViewer/Navigation/hooks/useNavigateToAnotherPage.tsx (1 hunks)
  • app/client/src/pages/AppViewer/Navigation/index.tsx (1 hunks)
  • app/client/src/pages/AppViewer/PageMenu.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • app/client/src/pages/AppViewer/PageMenu.tsx
🚧 Files skipped from review as they are similar to previous changes (5)
  • app/client/src/pages/AppViewer/Navigation/hooks/useNavigateToAnotherPage.tsx
  • app/client/src/pages/AppViewer/Navigation/components/MenuItem/index.tsx
  • app/client/src/ce/selectors/applicationSelectors.tsx
  • app/client/src/pages/AppViewer/Navigation/index.tsx
  • app/client/src/pages/AppViewer/Navigation/components/TopHeader.tsx
🧰 Additional context used
🧬 Code graph analysis (4)
app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx (5)
app/client/src/ce/selectors/applicationSelectors.tsx (5)
  • getIsApplicationSlugValid (64-65)
  • getIsValidatingAppSlug (62-63)
  • getIsFetchingAppSlugSuggestion (212-213)
  • getAppSlugSuggestion (215-216)
  • getIsPersistingAppSlug (60-61)
app/client/src/ce/entities/FeatureFlag.ts (1)
  • FEATURE_FLAG (2-68)
app/client/src/ce/constants/messages.ts (12)
  • STATIC_URL_CHANGE_SUCCESS (1938-1939)
  • STATIC_URL_DISABLED_SUCCESS (1936-1937)
  • GENERAL_SETTINGS_APP_URL_EMPTY_VALUE_MESSAGE (1932-1933)
  • GENERAL_SETTINGS_APP_URL_INVALID_MESSAGE (1923-1924)
  • GENERAL_SETTINGS_NAME_EMPTY_MESSAGE (1914-1915)
  • GENERAL_SETTINGS_APP_ICON_LABEL (1918-1918)
  • GENERAL_SETTINGS_APP_URL_LABEL (1919-1919)
  • GENERAL_SETTINGS_APP_URL_PLACEHOLDER_FETCHING (1921-1922)
  • GENERAL_SETTINGS_APP_URL_PLACEHOLDER (1920-1920)
  • GENERAL_SETTINGS_APP_URL_CHECKING_MESSAGE (1927-1928)
  • GENERAL_SETTINGS_APP_URL_AVAILABLE_MESSAGE (1929-1929)
  • GENERAL_SETTINGS_APP_URL_UNAVAILABLE_MESSAGE (1930-1931)
app/client/src/ce/actions/applicationActions.ts (6)
  • enableStaticUrl (322-330)
  • persistAppSlug (82-90)
  • resetAppSlugValidation (341-345)
  • validateAppSlug (92-99)
  • fetchAppSlugSuggestion (101-108)
  • disableStaticUrl (332-339)
app/client/src/ce/api/ApplicationApi.tsx (5)
  • enableStaticUrl (544-552)
  • persistAppSlug (522-533)
  • validateAppSlug (535-542)
  • fetchAppSlugSuggestion (560-566)
  • disableStaticUrl (554-558)
app/client/src/pages/AppIDE/components/AppSettings/components/PageSettings.tsx (9)
app/client/src/entities/Page/types.ts (1)
  • Page (1-13)
app/client/src/selectors/editorSelectors.tsx (5)
  • getIsStaticUrlEnabled (253-254)
  • getIsPersistingPageSlug (288-291)
  • getIsValidatingPageSlug (298-299)
  • getIsPageSlugValid (301-302)
  • getPageList (163-164)
app/client/src/ce/selectors/applicationSelectors.tsx (1)
  • getCurrentApplication (46-50)
app/client/src/ce/constants/messages.ts (17)
  • PAGE_SETTINGS_PAGE_SLUG_DEPLOY_MESSAGE (1950-1951)
  • PAGE_SETTINGS_PAGE_SLUG_CHECKING_MESSAGE (1945-1946)
  • PAGE_SETTINGS_PAGE_SLUG_AVAILABLE_MESSAGE (1947-1947)
  • PAGE_SETTINGS_PAGE_SLUG_UNAVAILABLE_MESSAGE (1948-1949)
  • PAGE_SETTINGS_NAME_EMPTY_MESSAGE (1963-1964)
  • PAGE_SETTINGS_ACTION_NAME_CONFLICT_ERROR (1980-1981)
  • PAGE_SETTINGS_PAGE_NAME_CONFLICTING_SLUG_MESSAGE (1952-1953)
  • PAGE_SETTINGS_PAGE_NAME_LABEL (1962-1962)
  • PAGE_SETTINGS_PAGE_URL_VERSION_UPDATE_1 (1968-1968)
  • PAGE_SETTINGS_PAGE_URL_VERSION_UPDATE_2 (1969-1969)
  • PAGE_SETTINGS_PAGE_URL_VERSION_UPDATE_3 (1970-1971)
  • PAGE_SETTINGS_PAGE_URL_LABEL (1967-1967)
  • PAGE_SETTINGS_SHOW_PAGE_NAV (1972-1972)
  • PAGE_SETTINGS_SHOW_PAGE_NAV_TOOLTIP (1973-1974)
  • PAGE_SETTINGS_SET_AS_HOMEPAGE (1975-1975)
  • PAGE_SETTINGS_SET_AS_HOMEPAGE_TOOLTIP (1976-1977)
  • PAGE_SETTINGS_SET_AS_HOMEPAGE_TOOLTIP_NON_HOME_PAGE (1978-1979)
app/client/src/utils/helpers.tsx (1)
  • isNameValid (521-534)
app/client/src/ce/utils/BusinessFeatures/permissionPageHelpers.tsx (1)
  • getHasManagePagePermission (112-118)
app/client/src/api/PageApi.tsx (2)
  • persistPageSlug (306-311)
  • validatePageSlug (313-318)
app/client/src/actions/pageActions.tsx (2)
  • persistPageSlug (709-717)
  • validatePageSlug (719-727)
app/client/src/pages/AppIDE/components/AppSettings/utils.ts (1)
  • filterAccentedAndSpecialCharacters (96-100)
app/client/src/ce/sagas/ApplicationSagas.tsx (4)
app/client/src/ce/selectors/applicationSelectors.tsx (1)
  • getCurrentApplication (46-50)
app/client/src/ce/api/ApplicationApi.tsx (1)
  • ApplicationApi (291-567)
app/client/src/sagas/ErrorSagas.tsx (1)
  • validateResponse (100-155)
app/client/src/ce/constants/messages.ts (1)
  • ERROR_IN_DISABLING_STATIC_URL (1934-1935)
app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx (2)
app/client/src/ce/constants/ReduxActionConstants.tsx (2)
  • ReduxActionTypes (1321-1365)
  • ReduxActionErrorTypes (1367-1394)
app/client/src/actions/ReduxActionTypes.ts (1)
  • ReduxAction (9-12)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: perform-test / client-build / client-build
  • GitHub Check: perform-test / rts-build / build
  • GitHub Check: perform-test / server-build / server-unit-tests
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: client-unit-tests / client-unit-tests
  • GitHub Check: client-prettier / prettier-check
  • GitHub Check: client-build / client-build
🔇 Additional comments (2)
app/client/src/ce/sagas/ApplicationSagas.tsx (2)

197-207: Publish flow waits for fresh app before building URL — good.

This ensures static slugs (if enabled) are reflected before opening the viewer.


1185-1241: Persist app slug request shape LGTM.

Uses only branchedApplicationId and uniqueApplicationSlug as per API; re-fetch on success is correct.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
app/client/src/ce/middlewares/RouteParamsMiddleware.ts (1)

120-129: Bug: application.baseid typo breaks URL params.

Should be baseId. As written, baseApplicationId becomes undefined.

-      appParams = {
-        baseApplicationId: application.baseid,
+      appParams = {
+        baseApplicationId: application.baseId,
         applicationSlug: application.slug,
         applicationVersion: application.applicationVersion,
         staticApplicationSlug: application?.staticUrlSettings?.uniqueSlug || "",
       };
app/client/src/ce/entities/URLRedirect/URLAssembly.ts (1)

241-248: Reset staticApplicationSlug when resetting URL params.

Avoid leaking a prior app’s static slug into subsequent routes.

  resetURLParams() {
    this.appParams = {
      baseApplicationId: "",
-     applicationSlug: "",
+     applicationSlug: "",
+     staticApplicationSlug: "",
    };
    this.pageParams = {};
  }
♻️ Duplicate comments (3)
app/client/src/ce/middlewares/RouteParamsMiddleware.ts (1)

131-139: Wrap case body to avoid leaking const declarations across cases.

Block-scope the declarations in CLONE_PAGE_SUCCESS.

-    case ReduxActionTypes.CLONE_PAGE_SUCCESS:
-      const { basePageId, pageSlug, uniqueSlug } = action.payload;
+    case ReduxActionTypes.CLONE_PAGE_SUCCESS: {
+      const { basePageId, pageSlug, uniqueSlug } = action.payload;
       pageParams = [
         {
           basePageId,
           pageSlug,
           staticPageSlug: uniqueSlug || "",
         },
       ];
       break;
+    }
app/client/src/pages/AppIDE/components/AppSettings/components/PageSettings.tsx (1)

539-545: Fix CSS class typo (extra closing parenthesis).

The utility is invalid: extra “)”.

- <strong className="text-[color:var(--appsmith-color-black-800))]">
+ <strong className="text-[color:var(--appsmith-color-black-800)]">
app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx (1)

292-299: Fix CSS class typo (extra closing parenthesis).

Invalid color utility.

-  <strong className="text-[color:var(--appsmith-color-black-800))]">
+  <strong className="text-[color:var(--appsmith-color-black-800)]">
🧹 Nitpick comments (7)
app/client/src/pages/AppViewer/index.tsx (3)

168-181: Guard baseApplicationId for static routes.

Static viewer paths don’t carry baseApplicationId. Pass an empty string to avoid undefined leaking into the init payload.

       dispatch(
         initAppViewerAction({
-          baseApplicationId,
+          baseApplicationId: baseApplicationId || "",
           branch,
           basePageId: resolvedBasePageId || "",
           mode: APP_MODE.PUBLISHED,
           staticApplicationSlug,
           staticPageSlug,
         }),
       );

112-121: Type the selector arg and handle explicit nulls from slug lookup.

Minor: add DefaultRootState type and coalesce null to undefined for downstream checks.

- const resolvedBasePageIdFromSlug = useSelector((state) =>
-   staticPageSlug
-     ? getBasePageIdFromStaticSlug(state, staticPageSlug)
-     : undefined,
- );
+ const resolvedBasePageIdFromSlug = useSelector((state: DefaultRootState) => {
+   if (!staticPageSlug) return undefined;
+   const id = getBasePageIdFromStaticSlug(state, staticPageSlug);
+   return id ?? undefined;
+ });

205-218: Trim unused dependency to avoid extra re-renders.

pathname isn’t used inside the effect.

-  }, [
+  }, [
     baseApplicationId,
     branch,
     dispatch,
     pages,
     prevValues?.resolvedBasePageId,
     prevValues?.branch,
     prevValues?.location,
     props.location,
     resolvedBasePageId,
     staticApplicationSlug,
     staticPageSlug,
-    pathname,
   ]);
app/client/src/pages/AppIDE/components/AppSettings/components/PageSettings.tsx (1)

487-503: Localize the “Page slug” label and placeholder.

Ensure consistency with the rest of the file that uses createMessage().

- label="Page slug"
+ label={createMessage(PAGE_SETTINGS_PAGE_URL_LABEL)}
...
- placeholder="Page slug"
+ placeholder={createMessage(PAGE_SETTINGS_PAGE_URL_LABEL)}
app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx (2)

221-243: Debounce app slug availability checks to reduce API churn.

Dispatching validateAppSlug on every keypress can flood the API.

+ // memoized debounced validator
+ const debouncedValidateAppSlug = React.useMemo(
+   () => debounce((slug: string) => dispatch(validateAppSlug(slug)), 300),
+   [dispatch],
+ );
  const onSlugChange = useCallback(
    (value: string) => {
      const normalizedValue = value.toLowerCase().replace(/\s+/g, "-");
      if (normalizedValue && normalizedValue.trim().length > 0) {
        const isValid = APPLICATION_SLUG_REGEX.test(normalizedValue);
        setIsClientSideSlugValid(isValid);
        if (isValid) {
-         dispatch(validateAppSlug(normalizedValue));
+         debouncedValidateAppSlug(normalizedValue);
        }
      } else {
        setIsClientSideSlugValid(true);
      }
      setApplicationSlug(normalizedValue);
    },
-   [dispatch],
+   [debouncedValidateAppSlug],
  );

100-114: Use backend “enabled” flag as the toggle source of truth.

Initialize and sync the switch from application.staticUrlSettings.enabled, not slug presence.

- const [isStaticUrlToggleEnabled, setIsStaticUrlToggleEnabled] =
-   useState(!!applicationSlug);
+ const [isStaticUrlToggleEnabled, setIsStaticUrlToggleEnabled] =
+   useState(!!application?.staticUrlSettings?.enabled);
+ useEffect(() => {
+   setIsStaticUrlToggleEnabled(!!application?.staticUrlSettings?.enabled);
+ }, [application?.staticUrlSettings?.enabled]);

Also applies to: 115-121

app/client/src/selectors/editorSelectors.tsx (1)

179-198: Solid implementation of parameterized selector.

The logic correctly handles edge cases and uses the standard pattern for parameterized selectors with createSelector.

Consider replacing any with DefaultRootState for the unused state parameter to maintain type safety:

  export const getBasePageIdFromStaticSlug = createSelector(
-   // eslint-disable-next-line @typescript-eslint/no-explicit-any
-   [getPageList, (_: any, staticPageSlug: string) => staticPageSlug],
+   [getPageList, (_: DefaultRootState, staticPageSlug: string) => staticPageSlug],
    (pages: Page[], staticPageSlug: string) => {
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5f0090a and a6a2a97.

📒 Files selected for processing (8)
  • app/client/src/ce/entities/URLRedirect/URLAssembly.ts (7 hunks)
  • app/client/src/ce/middlewares/RouteParamsMiddleware.ts (8 hunks)
  • app/client/src/entities/Application/types.ts (1 hunks)
  • app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx (7 hunks)
  • app/client/src/pages/AppIDE/components/AppSettings/components/PageSettings.tsx (13 hunks)
  • app/client/src/pages/AppViewer/AppViewerPageContainer.tsx (4 hunks)
  • app/client/src/pages/AppViewer/index.tsx (5 hunks)
  • app/client/src/selectors/editorSelectors.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • app/client/src/pages/AppViewer/AppViewerPageContainer.tsx
  • app/client/src/entities/Application/types.ts
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: ashit-rath
PR: appsmithorg/appsmith#41312
File: app/client/src/sagas/InitSagas.ts:260-271
Timestamp: 2025-10-28T03:30:58.271Z
Learning: In app/client/src/sagas/InitSagas.ts, when constructing consolidatedApiParams for static page URLs, the code intentionally reuses applicationId and defaultPageId fields to pass staticApplicationSlug and staticPageSlug values respectively. This is by design, even though ConsolidatedApiParams type has dedicated staticApplicationSlug and staticPageSlug fields.
📚 Learning: 2025-10-28T03:30:58.271Z
Learnt from: ashit-rath
PR: appsmithorg/appsmith#41312
File: app/client/src/sagas/InitSagas.ts:260-271
Timestamp: 2025-10-28T03:30:58.271Z
Learning: In app/client/src/sagas/InitSagas.ts, when constructing consolidatedApiParams for static page URLs, the code intentionally reuses applicationId and defaultPageId fields to pass staticApplicationSlug and staticPageSlug values respectively. This is by design, even though ConsolidatedApiParams type has dedicated staticApplicationSlug and staticPageSlug fields.

Applied to files:

  • app/client/src/pages/AppIDE/components/AppSettings/components/PageSettings.tsx
  • app/client/src/pages/AppViewer/index.tsx
  • app/client/src/ce/entities/URLRedirect/URLAssembly.ts
  • app/client/src/ce/middlewares/RouteParamsMiddleware.ts
🧬 Code graph analysis (4)
app/client/src/pages/AppIDE/components/AppSettings/components/PageSettings.tsx (10)
app/client/src/entities/Page/types.ts (1)
  • Page (1-13)
app/client/src/selectors/editorSelectors.tsx (7)
  • getCurrentApplicationId (240-241)
  • selectApplicationVersion (249-251)
  • getIsStaticUrlEnabled (253-254)
  • getIsPersistingPageSlug (288-291)
  • getIsValidatingPageSlug (298-299)
  • getIsPageSlugValid (301-302)
  • getPageList (163-164)
app/client/src/ce/selectors/applicationSelectors.tsx (1)
  • getCurrentApplication (46-50)
app/client/src/ce/entities/FeatureFlag.ts (1)
  • FEATURE_FLAG (2-68)
app/client/src/ce/constants/messages.ts (17)
  • PAGE_SETTINGS_PAGE_SLUG_DEPLOY_MESSAGE (1950-1951)
  • PAGE_SETTINGS_PAGE_SLUG_CHECKING_MESSAGE (1945-1946)
  • PAGE_SETTINGS_PAGE_SLUG_AVAILABLE_MESSAGE (1947-1947)
  • PAGE_SETTINGS_PAGE_SLUG_UNAVAILABLE_MESSAGE (1948-1949)
  • PAGE_SETTINGS_NAME_EMPTY_MESSAGE (1963-1964)
  • PAGE_SETTINGS_ACTION_NAME_CONFLICT_ERROR (1980-1981)
  • PAGE_SETTINGS_PAGE_NAME_CONFLICTING_SLUG_MESSAGE (1952-1953)
  • PAGE_SETTINGS_PAGE_NAME_LABEL (1962-1962)
  • PAGE_SETTINGS_PAGE_URL_VERSION_UPDATE_1 (1968-1968)
  • PAGE_SETTINGS_PAGE_URL_VERSION_UPDATE_2 (1969-1969)
  • PAGE_SETTINGS_PAGE_URL_VERSION_UPDATE_3 (1970-1971)
  • PAGE_SETTINGS_PAGE_URL_LABEL (1967-1967)
  • PAGE_SETTINGS_SHOW_PAGE_NAV (1972-1972)
  • PAGE_SETTINGS_SHOW_PAGE_NAV_TOOLTIP (1973-1974)
  • PAGE_SETTINGS_SET_AS_HOMEPAGE (1975-1975)
  • PAGE_SETTINGS_SET_AS_HOMEPAGE_TOOLTIP (1976-1977)
  • PAGE_SETTINGS_SET_AS_HOMEPAGE_TOOLTIP_NON_HOME_PAGE (1978-1979)
app/client/src/utils/helpers.tsx (1)
  • isNameValid (521-534)
app/client/src/ce/utils/BusinessFeatures/permissionPageHelpers.tsx (1)
  • getHasManagePagePermission (112-118)
app/client/src/api/PageApi.tsx (2)
  • persistPageSlug (306-311)
  • validatePageSlug (313-318)
app/client/src/actions/pageActions.tsx (2)
  • persistPageSlug (709-717)
  • validatePageSlug (719-727)
app/client/src/pages/AppIDE/components/AppSettings/utils.ts (1)
  • filterAccentedAndSpecialCharacters (96-100)
app/client/src/pages/AppViewer/index.tsx (4)
app/client/src/selectors/editorSelectors.tsx (2)
  • getPageList (163-164)
  • getBasePageIdFromStaticSlug (179-198)
app/client/src/pages/utils.ts (1)
  • getIsBranchUpdated (5-16)
app/client/src/actions/initActions.ts (1)
  • initAppViewerAction (38-57)
app/client/src/actions/pageActions.tsx (1)
  • fetchPublishedPageResources (302-313)
app/client/src/ce/entities/URLRedirect/URLAssembly.ts (1)
app/client/src/ce/constants/routes/appRoutes.ts (4)
  • BUILDER_PATH_STATIC (27-27)
  • VIEWER_PATH_STATIC (28-28)
  • PLACEHOLDER_PAGE_SLUG (201-201)
  • PLACEHOLDER_APP_SLUG (199-199)
app/client/src/selectors/editorSelectors.tsx (2)
app/client/src/ce/selectors/entitiesSelector.ts (1)
  • getPageList (1053-1056)
app/client/src/entities/Page/types.ts (1)
  • Page (1-13)
🪛 Biome (2.1.2)
app/client/src/ce/middlewares/RouteParamsMiddleware.ts

[error] 131-131: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: perform-test / server-build / server-unit-tests
  • GitHub Check: perform-test / client-build / client-build
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: client-unit-tests / client-unit-tests
  • GitHub Check: client-build / client-build
  • GitHub Check: client-prettier / prettier-check
🔇 Additional comments (2)
app/client/src/selectors/editorSelectors.tsx (2)

253-254: LGTM!

Clean selector with proper optional chaining and boolean coercion.


288-302: LGTM!

These plain selector functions are correctly implemented for simple property access. Using plain functions instead of createSelector is appropriate here and more performant for direct state access. The default values and optional chaining ensure safe fallbacks.

@ashit-rath ashit-rath removed the request for review from rahulbarwal October 28, 2025 09:49
ankitakinger
ankitakinger previously approved these changes Oct 28, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx (1)

305-312: Fix class name typo in AppUrlContent.

Extra closing parenthesis breaks the CSS variable reference.

Apply this diff to fix:

-      <strong className="text-[color:var(--appsmith-color-black-800))]">
+      <strong className="text-[color:var(--appsmith-color-black-800)]">
🧹 Nitpick comments (5)
app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx (1)

823-831: Consider clearing appSlugSuggestion consistently across all success handlers.

ENABLE_STATIC_URL_SUCCESS clears appSlugSuggestion (line 829), but DISABLE_STATIC_URL_SUCCESS and PERSIST_APP_SLUG_SUCCESS don't. This leaves potentially stale suggestion data in state.

If suggestions are only relevant during enablement, the current approach is fine. Otherwise, consider clearing suggestions in all success handlers for consistency.

  [ReduxActionTypes.DISABLE_STATIC_URL_SUCCESS]: (
    state: ApplicationsReduxState,
  ) => {
    return {
      ...state,
      isPersistingAppSlug: false,
+     appSlugSuggestion: "",
    };
  },
  [ReduxActionTypes.PERSIST_APP_SLUG_SUCCESS]: (
    state: ApplicationsReduxState,
  ) => {
    return {
      ...state,
      isPersistingAppSlug: false,
+     appSlugSuggestion: "",
    };
  },

Also applies to: 846-853, 868-875

app/client/src/entities/URLRedirect/SlugURLRedirect.ts (1)

29-35: Conditional static slug computation is correct.

The mode-based check ensures static slugs are only used in viewer mode (APP_MODE.PUBLISHED), which aligns with the PR objectives. The optional chaining and empty string fallbacks provide graceful degradation when static URLs aren't configured.

Consider extracting the mode check to reduce repetition:

-      // Only use static slugs for viewer mode, not for edit mode
-      const staticApplicationSlug =
-        this._mode === APP_MODE.PUBLISHED
-          ? currentApplication?.staticUrlSettings?.uniqueSlug || ""
-          : "";
-      const staticPageSlug =
-        this._mode === APP_MODE.PUBLISHED ? currentPage?.uniqueSlug || "" : "";
+      // Only use static slugs for viewer mode, not for edit mode
+      const isPublishedMode = this._mode === APP_MODE.PUBLISHED;
+      const staticApplicationSlug = isPublishedMode
+        ? currentApplication?.staticUrlSettings?.uniqueSlug || ""
+        : "";
+      const staticPageSlug = isPublishedMode
+        ? currentPage?.uniqueSlug || ""
+        : "";
app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx (3)

119-124: Optimize effect dependencies.

The dependency array includes both application and application?.name. Since only the name property is used (line 121), including the entire application object causes unnecessary re-runs when unrelated properties change.

Apply this diff:

   useEffect(
     function updateApplicationName() {
       !isSavingAppName && setApplicationName(application?.name);
     },
-    [application, application?.name, isSavingAppName],
+    [application?.name, isSavingAppName],
   );

195-211: Optimize debounced callback dependencies.

The dependency array includes the entire application object, but only application?.name is accessed (line 197). This causes the debounced function to be recreated whenever any application property changes.

Apply this diff:

     [applicationName, application, applicationId, isAppNameValid, dispatch],
+    [applicationName, application?.name, applicationId, isAppNameValid, dispatch],
   );

356-373: Remove unused dependency from useMemo.

isApplicationSlugValid is listed in the dependency array (line 372) but is never referenced in the function body. This causes unnecessary recomputation when server validation state changes.

Apply this diff:

   }, [
     isFetchingAppSlugSuggestion,
     applicationSlug,
     isClientSideSlugValid,
-    isApplicationSlugValid,
   ]);
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a6a2a97 and fe6d482.

📒 Files selected for processing (6)
  • app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx (3 hunks)
  • app/client/src/entities/URLRedirect/SlugURLRedirect.ts (1 hunks)
  • app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx (7 hunks)
  • app/client/src/sagas/InitSagas.ts (9 hunks)
  • app/client/src/sagas/__tests__/initSagas.test.ts (2 hunks)
  • app/client/src/utils/helpers.tsx (8 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/client/src/sagas/tests/initSagas.test.ts
🧰 Additional context used
🧠 Learnings (17)
📓 Common learnings
Learnt from: ashit-rath
PR: appsmithorg/appsmith#41312
File: app/client/src/sagas/InitSagas.ts:260-271
Timestamp: 2025-10-28T03:30:58.299Z
Learning: In app/client/src/sagas/InitSagas.ts, when constructing consolidatedApiParams for static page URLs, the code intentionally reuses applicationId and defaultPageId fields to pass staticApplicationSlug and staticPageSlug values respectively. This is by design, even though ConsolidatedApiParams type has dedicated staticApplicationSlug and staticPageSlug fields.
Learnt from: ashit-rath
PR: appsmithorg/appsmith#41312
File: app/client/src/pages/AppIDE/components/AppSettings/components/PageSettings.tsx:330-359
Timestamp: 2025-10-28T09:17:22.519Z
Learning: In the Appsmith codebase, slug normalization for static URLs (application slugs and page slugs) handles lowercase conversion on the backend. The frontend helper `filterAccentedAndSpecialCharacters` in `app/client/src/pages/AppIDE/components/AppSettings/utils.ts` intentionally preserves the user's input casing to avoid modifying the entered value too drastically, as the backend will normalize to lowercase during persistence.
Learnt from: ashit-rath
PR: appsmithorg/appsmith#33809
File: app/client/src/workers/Evaluation/evaluate.ts:209-229
Timestamp: 2024-10-08T15:32:34.115Z
Learning: User ashit-rath prefers using `forEach` over `for...of` for iterating over objects and arrays in JavaScript.
Learnt from: ashit-rath
PR: appsmithorg/appsmith#33809
File: app/client/src/workers/Evaluation/evaluate.ts:209-229
Timestamp: 2024-07-26T21:12:57.228Z
Learning: User ashit-rath prefers using `forEach` over `for...of` for iterating over objects and arrays in JavaScript.
📚 Learning: 2025-10-28T03:30:58.299Z
Learnt from: ashit-rath
PR: appsmithorg/appsmith#41312
File: app/client/src/sagas/InitSagas.ts:260-271
Timestamp: 2025-10-28T03:30:58.299Z
Learning: In app/client/src/sagas/InitSagas.ts, when constructing consolidatedApiParams for static page URLs, the code intentionally reuses applicationId and defaultPageId fields to pass staticApplicationSlug and staticPageSlug values respectively. This is by design, even though ConsolidatedApiParams type has dedicated staticApplicationSlug and staticPageSlug fields.

Applied to files:

  • app/client/src/entities/URLRedirect/SlugURLRedirect.ts
  • app/client/src/sagas/InitSagas.ts
  • app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx
  • app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx
  • app/client/src/utils/helpers.tsx
📚 Learning: 2025-10-28T09:17:22.519Z
Learnt from: ashit-rath
PR: appsmithorg/appsmith#41312
File: app/client/src/pages/AppIDE/components/AppSettings/components/PageSettings.tsx:330-359
Timestamp: 2025-10-28T09:17:22.519Z
Learning: In the Appsmith codebase, slug normalization for static URLs (application slugs and page slugs) handles lowercase conversion on the backend. The frontend helper `filterAccentedAndSpecialCharacters` in `app/client/src/pages/AppIDE/components/AppSettings/utils.ts` intentionally preserves the user's input casing to avoid modifying the entered value too drastically, as the backend will normalize to lowercase during persistence.

Applied to files:

  • app/client/src/entities/URLRedirect/SlugURLRedirect.ts
  • app/client/src/sagas/InitSagas.ts
  • app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx
  • app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx
  • app/client/src/utils/helpers.tsx
📚 Learning: 2024-12-10T10:52:38.873Z
Learnt from: brayn003
PR: appsmithorg/appsmith#38060
File: app/client/src/git/sagas/fetchLocalProfileSaga.ts:8-13
Timestamp: 2024-12-10T10:52:38.873Z
Learning: In `app/client/src/git/sagas/fetchLocalProfileSaga.ts` and similar Git sagas, error handling for `baseArtifactId` is managed outside the scope, so validation checks for `baseArtifactId` within the saga functions are unnecessary.

Applied to files:

  • app/client/src/sagas/InitSagas.ts
  • app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx
📚 Learning: 2024-07-26T21:12:57.228Z
Learnt from: ankitakinger
PR: appsmithorg/appsmith#29965
File: app/client/src/utils/storage.ts:129-129
Timestamp: 2024-07-26T21:12:57.228Z
Learning: The `migrateAppIdToEditorId` function in `app/client/src/utils/storage.ts` is intended to be called only when `appId` is present and `editorId` is not in the payload. This context should be considered in future reviews related to this function.

Applied to files:

  • app/client/src/sagas/InitSagas.ts
  • app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx
📚 Learning: 2024-07-26T21:12:57.228Z
Learnt from: ankitakinger
PR: appsmithorg/appsmith#29965
File: app/client/src/ce/sagas/ApplicationSagas.tsx:736-742
Timestamp: 2024-07-26T21:12:57.228Z
Learning: The use of `editorId` instead of `appId` is an intentional change in the PR and is part of reverting to a previous functionality.

Applied to files:

  • app/client/src/sagas/InitSagas.ts
📚 Learning: 2025-04-28T16:16:02.155Z
Learnt from: brayn003
PR: appsmithorg/appsmith#40462
File: app/client/src/git/components/ImportOverrideModal/ImportOverrideModalView.tsx:34-40
Timestamp: 2025-04-28T16:16:02.155Z
Learning: The Appsmith team prefers not to include HTML markup in string constants. Text styling or emphasis should be handled through proper React components rather than HTML tags in strings.

Applied to files:

  • app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx
📚 Learning: 2024-12-11T08:33:24.352Z
Learnt from: brayn003
PR: appsmithorg/appsmith#38088
File: app/client/src/git/components/GitQuickActions/BranchButton/index.tsx:72-74
Timestamp: 2024-12-11T08:33:24.352Z
Learning: In the 'BranchButton' component in 'app/client/src/git/components/GitQuickActions/BranchButton/index.tsx' (TypeScript, React), the `useEffect` hook that checks for label ellipsis does not need to include `currentBranch` in its dependency array.

Applied to files:

  • app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx
📚 Learning: 2024-10-08T15:32:34.115Z
Learnt from: alex-golovanov
PR: appsmithorg/appsmith#36665
File: app/client/src/IDE/Components/FileTab/styles.tsx:19-19
Timestamp: 2024-10-08T15:32:34.115Z
Learning: Do not suggest replacing hardcoded `padding-top: 6px;` with design variables in `app/client/src/IDE/Components/FileTab/styles.tsx`.

Applied to files:

  • app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx
📚 Learning: 2024-11-12T11:42:28.998Z
Learnt from: ankitakinger
PR: appsmithorg/appsmith#37330
File: app/client/src/pages/common/SearchBar/HomepageHeaderAction.tsx:95-95
Timestamp: 2024-11-12T11:42:28.998Z
Learning: In icon provider components within the TypeScript/React codebase, old settings icons like `"settings-2-line"` and `"settings-control"` are intentionally provided alongside new icons. These references are acceptable and should not be flagged for updates.

Applied to files:

  • app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx
📚 Learning: 2024-11-12T07:37:42.598Z
Learnt from: ankitakinger
PR: appsmithorg/appsmith#37330
File: app/client/src/pages/Editor/gitSync/components/GitChangesList/StaticChange.tsx:52-52
Timestamp: 2024-11-12T07:37:42.598Z
Learning: The icon provider components in `app/client/packages/design-system/widgets-old/src/Icon/index.tsx` and `app/client/packages/design-system/ads/src/Icon/Icon.provider.tsx` should provide both `settings-2-line` and `settings-v3` icons and should not be updated to remove the old icon.

Applied to files:

  • app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx
📚 Learning: 2024-12-10T10:53:17.146Z
Learnt from: brayn003
PR: appsmithorg/appsmith#38060
File: app/client/src/git/components/GitQuickActions/helpers/getPullButtonStatus.ts:16-24
Timestamp: 2024-12-10T10:53:17.146Z
Learning: In the `getPullBtnStatus` function (`app/client/src/git/components/GitQuickActions/helpers/getPullButtonStatus.ts`), default parameter values should be explicitly mentioned to handle component state properly, even if all props are required.

Applied to files:

  • app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx
📚 Learning: 2024-12-05T10:56:13.739Z
Learnt from: brayn003
PR: appsmithorg/appsmith#37984
File: app/client/src/git/requests/fetchSSHKeyRequest.ts:5-9
Timestamp: 2024-12-05T10:56:13.739Z
Learning: In `app/client/src/git/requests/fetchSSHKeyRequest.ts`, the `fetchSSHKeyRequest` function does not require explicit error handling for `baseApplicationId`; the function should throw an error naturally if `baseApplicationId` is missing or invalid.

Applied to files:

  • app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx
📚 Learning: 2024-12-16T19:47:22.699Z
Learnt from: brayn003
PR: appsmithorg/appsmith#38171
File: app/client/src/git/ce/components/DefaultBranch/DefaultBranchView.tsx:92-100
Timestamp: 2024-12-16T19:47:22.699Z
Learning: In this codebase, action creators like `updateDefaultBranch` do not throw errors, so adding error handling around them is unnecessary.

Applied to files:

  • app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx
📚 Learning: 2024-07-26T21:12:57.228Z
Learnt from: sneha122
PR: appsmithorg/appsmith#30012
File: app/client/src/pages/Editor/DataSourceEditor/RestAPIDatasourceForm.tsx:679-682
Timestamp: 2024-07-26T21:12:57.228Z
Learning: The user `sneha122` has confirmed the resolution of the feedback regarding the redundancy of `|| false` in the `_.get` expression within the `RestAPIDatasourceForm.tsx` file.

Applied to files:

  • app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx
📚 Learning: 2024-07-26T21:12:57.228Z
Learnt from: sharat87
PR: appsmithorg/appsmith#30252
File: deploy/docker/fs/usr/lib/python3/dist-packages/supervisor/appsmith_supervisor_stdout.py:21-29
Timestamp: 2024-07-26T21:12:57.228Z
Learning: The user has confirmed that the suggested changes to handle potential exceptions and improve the robustness of the `main` function in `appsmith_supervisor_stdout.py` are acceptable.

Applied to files:

  • app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx
📚 Learning: 2024-10-21T13:17:59.251Z
Learnt from: brayn003
PR: appsmithorg/appsmith#36989
File: app/client/packages/git/src/actions/helpers/createSingleArtifactAction.ts:52-68
Timestamp: 2024-10-21T13:17:59.251Z
Learning: In this codebase, when using Redux Toolkit's createSlice from Redux Toolkit, we can directly mutate the state within reducers since Immer handles immutability internally.

Applied to files:

  • app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx
🧬 Code graph analysis (5)
app/client/src/entities/URLRedirect/SlugURLRedirect.ts (1)
app/client/src/utils/helpers.tsx (1)
  • getUpdatedRoute (1042-1095)
app/client/src/sagas/InitSagas.ts (3)
app/client/src/utils/helpers.tsx (1)
  • getSearchQuery (806-810)
app/client/src/actions/initActions.ts (2)
  • initEditorAction (21-26)
  • initAppViewerAction (38-57)
app/client/src/ce/pages/Editor/Explorer/helpers.tsx (2)
  • isViewerPath (135-137)
  • matchViewerPathTyped (122-133)
app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx (6)
app/client/src/selectors/editorSelectors.tsx (1)
  • getCurrentBasePageId (176-177)
app/client/src/ce/selectors/applicationSelectors.tsx (6)
  • getIsSavingAppName (56-57)
  • getIsApplicationSlugValid (64-65)
  • getIsValidatingAppSlug (62-63)
  • getIsFetchingAppSlugSuggestion (212-213)
  • getAppSlugSuggestion (215-216)
  • getIsPersistingAppSlug (60-61)
app/client/src/ce/entities/FeatureFlag.ts (1)
  • FEATURE_FLAG (2-68)
app/client/src/ce/constants/messages.ts (12)
  • STATIC_URL_CHANGE_SUCCESS (1938-1939)
  • STATIC_URL_DISABLED_SUCCESS (1936-1937)
  • GENERAL_SETTINGS_APP_URL_EMPTY_VALUE_MESSAGE (1932-1933)
  • GENERAL_SETTINGS_APP_URL_INVALID_MESSAGE (1923-1924)
  • GENERAL_SETTINGS_NAME_EMPTY_MESSAGE (1914-1915)
  • GENERAL_SETTINGS_APP_ICON_LABEL (1918-1918)
  • GENERAL_SETTINGS_APP_URL_LABEL (1919-1919)
  • GENERAL_SETTINGS_APP_URL_PLACEHOLDER_FETCHING (1921-1922)
  • GENERAL_SETTINGS_APP_URL_PLACEHOLDER (1920-1920)
  • GENERAL_SETTINGS_APP_URL_CHECKING_MESSAGE (1927-1928)
  • GENERAL_SETTINGS_APP_URL_AVAILABLE_MESSAGE (1929-1929)
  • GENERAL_SETTINGS_APP_URL_UNAVAILABLE_MESSAGE (1930-1931)
app/client/src/ce/actions/applicationActions.ts (6)
  • enableStaticUrl (322-330)
  • persistAppSlug (82-90)
  • resetAppSlugValidation (341-345)
  • validateAppSlug (92-99)
  • fetchAppSlugSuggestion (101-108)
  • disableStaticUrl (332-339)
app/client/src/ce/api/ApplicationApi.tsx (5)
  • enableStaticUrl (544-552)
  • persistAppSlug (522-533)
  • validateAppSlug (535-542)
  • fetchAppSlugSuggestion (560-566)
  • disableStaticUrl (554-558)
app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx (2)
app/client/src/ce/constants/ReduxActionConstants.tsx (2)
  • ReduxActionTypes (1321-1365)
  • ReduxActionErrorTypes (1367-1394)
app/client/src/actions/ReduxActionTypes.ts (1)
  • ReduxAction (9-12)
app/client/src/utils/helpers.tsx (1)
app/client/src/ce/constants/routes/appRoutes.ts (1)
  • VIEWER_PATH_STATIC (28-28)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: perform-test / rts-build / build
  • GitHub Check: perform-test / client-build / client-build
  • GitHub Check: perform-test / server-build / server-unit-tests
  • GitHub Check: client-build / client-build
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-prettier / prettier-check
  • GitHub Check: client-unit-tests / client-unit-tests
🔇 Additional comments (3)
app/client/src/entities/URLRedirect/SlugURLRedirect.ts (1)

37-49: Implementation correctly handles empty static slugs—no changes needed.

The downstream code consistently validates that both staticApplicationSlug and staticPageSlug are present using AND logic before applying static URL transformations. When either slug is empty, the code gracefully skips static URL handling and falls back to legacy URL patterns with basePageId. This pattern is enforced across all consuming code paths (InitSagas, Engine, AppIDELoader, MenuItem, etc.), making the implementation safe and robust.

app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx (2)

225-247: Verify frontend lowercase conversion approach.

Line 228 applies .toLowerCase() directly in the frontend. According to retrieved learnings, the filterAccentedAndSpecialCharacters helper intentionally preserves user input casing, with backend handling normalization. This code bypasses that helper and forces lowercase immediately. Confirm this is the intended UX for application slugs (different from page slugs) or if it should preserve casing like the helper does.

Based on learnings.


259-303: Modal slug computation logic verified—no issues found.

The code correctly handles all three scenarios:

  • Enable first time: Transitions from legacy format (appSlug/customSlug-pageId) to static format (staticAppSlug/uniqueSlug)
  • Change existing: Stays in static format while updating the slug
  • Disable: Transitions back from static (staticAppSlug/uniqueSlug) to legacy (appSlug/customSlug-pageId)

Page slug properties are used consistently throughout the codebase: uniqueSlug for static URLs, customSlug for legacy custom slugs, and slug as fallback. The page ID suffix is correctly included only in legacy format. The logic is sound.

@ashit-rath ashit-rath removed the ok-to-test Required label for CI label Oct 30, 2025
@ashit-rath ashit-rath added ok-to-test Required label for CI static-url Enables static and human-readable URLs for applications and pages. labels Oct 30, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx (1)

307-314: Fix class name typo in AppUrlContent.

Extra closing parenthesis breaks the CSS variable.

-      <strong className="text-[color:var(--appsmith-color-black-800))]">
+      <strong className="text-[color:var(--appsmith-color-black-800)]">
🧹 Nitpick comments (1)
app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx (1)

358-375: Remove unused dependency from memoization.

The isApplicationSlugValid is included in the dependency array but not used in the function body. This can cause unnecessary re-computation.

  }, [
    isFetchingAppSlugSuggestion,
    applicationSlug,
    isClientSideSlugValid,
-   isApplicationSlugValid,
  ]);
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ace227b and a74b4ac.

📒 Files selected for processing (1)
  • app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx (7 hunks)
🧰 Additional context used
🧠 Learnings (10)
📓 Common learnings
Learnt from: ashit-rath
PR: appsmithorg/appsmith#41312
File: app/client/src/sagas/InitSagas.ts:260-271
Timestamp: 2025-10-28T03:30:58.299Z
Learning: In app/client/src/sagas/InitSagas.ts, when constructing consolidatedApiParams for static page URLs, the code intentionally reuses applicationId and defaultPageId fields to pass staticApplicationSlug and staticPageSlug values respectively. This is by design, even though ConsolidatedApiParams type has dedicated staticApplicationSlug and staticPageSlug fields.
Learnt from: ashit-rath
PR: appsmithorg/appsmith#41312
File: app/client/src/utils/helpers.tsx:1124-1136
Timestamp: 2025-10-30T07:15:20.265Z
Learning: In app/client/src/utils/helpers.tsx, within the getUpdateRouteForSlugPath function, the pageSlug parameter extracted from the route includes the trailing hyphen (e.g., "home-page-" not "home-page"). Additionally, when the static slug conversion branch is executed, params.basePageId is guaranteed to be defined because the code path requires successful page data fetch from the server as a precondition.
Learnt from: ashit-rath
PR: appsmithorg/appsmith#41312
File: app/client/src/pages/AppIDE/components/AppSettings/components/PageSettings.tsx:330-359
Timestamp: 2025-10-28T09:17:22.519Z
Learning: In the Appsmith codebase, slug normalization for static URLs (application slugs and page slugs) handles lowercase conversion on the backend. The frontend helper `filterAccentedAndSpecialCharacters` in `app/client/src/pages/AppIDE/components/AppSettings/utils.ts` intentionally preserves the user's input casing to avoid modifying the entered value too drastically, as the backend will normalize to lowercase during persistence.
Learnt from: ashit-rath
PR: appsmithorg/appsmith#33809
File: app/client/src/workers/Evaluation/evaluate.ts:209-229
Timestamp: 2024-10-08T15:32:34.115Z
Learning: User ashit-rath prefers using `forEach` over `for...of` for iterating over objects and arrays in JavaScript.
Learnt from: ashit-rath
PR: appsmithorg/appsmith#33809
File: app/client/src/workers/Evaluation/evaluate.ts:209-229
Timestamp: 2024-07-26T21:12:57.228Z
Learning: User ashit-rath prefers using `forEach` over `for...of` for iterating over objects and arrays in JavaScript.
📚 Learning: 2025-10-28T09:17:22.519Z
Learnt from: ashit-rath
PR: appsmithorg/appsmith#41312
File: app/client/src/pages/AppIDE/components/AppSettings/components/PageSettings.tsx:330-359
Timestamp: 2025-10-28T09:17:22.519Z
Learning: In the Appsmith codebase, slug normalization for static URLs (application slugs and page slugs) handles lowercase conversion on the backend. The frontend helper `filterAccentedAndSpecialCharacters` in `app/client/src/pages/AppIDE/components/AppSettings/utils.ts` intentionally preserves the user's input casing to avoid modifying the entered value too drastically, as the backend will normalize to lowercase during persistence.

Applied to files:

  • app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx
📚 Learning: 2025-10-28T03:30:58.299Z
Learnt from: ashit-rath
PR: appsmithorg/appsmith#41312
File: app/client/src/sagas/InitSagas.ts:260-271
Timestamp: 2025-10-28T03:30:58.299Z
Learning: In app/client/src/sagas/InitSagas.ts, when constructing consolidatedApiParams for static page URLs, the code intentionally reuses applicationId and defaultPageId fields to pass staticApplicationSlug and staticPageSlug values respectively. This is by design, even though ConsolidatedApiParams type has dedicated staticApplicationSlug and staticPageSlug fields.

Applied to files:

  • app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx
📚 Learning: 2025-10-30T07:15:20.265Z
Learnt from: ashit-rath
PR: appsmithorg/appsmith#41312
File: app/client/src/utils/helpers.tsx:1124-1136
Timestamp: 2025-10-30T07:15:20.265Z
Learning: In app/client/src/utils/helpers.tsx, within the getUpdateRouteForSlugPath function, the pageSlug parameter extracted from the route includes the trailing hyphen (e.g., "home-page-" not "home-page"). Additionally, when the static slug conversion branch is executed, params.basePageId is guaranteed to be defined because the code path requires successful page data fetch from the server as a precondition.

Applied to files:

  • app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx
📚 Learning: 2025-10-30T07:17:49.624Z
Learnt from: ashit-rath
PR: appsmithorg/appsmith#41312
File: app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx:817-883
Timestamp: 2025-10-30T07:17:49.624Z
Learning: In app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx, the isErrorPersistingAppSlug flag is unused and should be removed. There is no corresponding selector to expose it, and no handlers set it to true.

Applied to files:

  • app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx
📚 Learning: 2025-04-28T16:16:02.155Z
Learnt from: brayn003
PR: appsmithorg/appsmith#40462
File: app/client/src/git/components/ImportOverrideModal/ImportOverrideModalView.tsx:34-40
Timestamp: 2025-04-28T16:16:02.155Z
Learning: The Appsmith team prefers not to include HTML markup in string constants. Text styling or emphasis should be handled through proper React components rather than HTML tags in strings.

Applied to files:

  • app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx
📚 Learning: 2024-12-11T08:33:24.352Z
Learnt from: brayn003
PR: appsmithorg/appsmith#38088
File: app/client/src/git/components/GitQuickActions/BranchButton/index.tsx:72-74
Timestamp: 2024-12-11T08:33:24.352Z
Learning: In the 'BranchButton' component in 'app/client/src/git/components/GitQuickActions/BranchButton/index.tsx' (TypeScript, React), the `useEffect` hook that checks for label ellipsis does not need to include `currentBranch` in its dependency array.

Applied to files:

  • app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx
📚 Learning: 2024-10-08T15:32:34.115Z
Learnt from: alex-golovanov
PR: appsmithorg/appsmith#36665
File: app/client/src/IDE/Components/FileTab/styles.tsx:19-19
Timestamp: 2024-10-08T15:32:34.115Z
Learning: Do not suggest replacing hardcoded `padding-top: 6px;` with design variables in `app/client/src/IDE/Components/FileTab/styles.tsx`.

Applied to files:

  • app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx
📚 Learning: 2024-11-12T11:42:28.998Z
Learnt from: ankitakinger
PR: appsmithorg/appsmith#37330
File: app/client/src/pages/common/SearchBar/HomepageHeaderAction.tsx:95-95
Timestamp: 2024-11-12T11:42:28.998Z
Learning: In icon provider components within the TypeScript/React codebase, old settings icons like `"settings-2-line"` and `"settings-control"` are intentionally provided alongside new icons. These references are acceptable and should not be flagged for updates.

Applied to files:

  • app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx
📚 Learning: 2024-11-12T07:37:42.598Z
Learnt from: ankitakinger
PR: appsmithorg/appsmith#37330
File: app/client/src/pages/Editor/gitSync/components/GitChangesList/StaticChange.tsx:52-52
Timestamp: 2024-11-12T07:37:42.598Z
Learning: The icon provider components in `app/client/packages/design-system/widgets-old/src/Icon/index.tsx` and `app/client/packages/design-system/ads/src/Icon/Icon.provider.tsx` should provide both `settings-2-line` and `settings-v3` icons and should not be updated to remove the old icon.

Applied to files:

  • app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx
🧬 Code graph analysis (1)
app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx (6)
app/client/src/selectors/editorSelectors.tsx (2)
  • getPageList (163-164)
  • getCurrentBasePageId (176-177)
app/client/src/ce/selectors/applicationSelectors.tsx (6)
  • getIsSavingAppName (56-57)
  • getIsApplicationSlugValid (64-65)
  • getIsValidatingAppSlug (62-63)
  • getIsFetchingAppSlugSuggestion (212-213)
  • getAppSlugSuggestion (215-216)
  • getIsPersistingAppSlug (60-61)
app/client/src/ce/entities/FeatureFlag.ts (1)
  • FEATURE_FLAG (2-68)
app/client/src/ce/constants/messages.ts (12)
  • STATIC_URL_CHANGE_SUCCESS (1938-1939)
  • STATIC_URL_DISABLED_SUCCESS (1936-1937)
  • GENERAL_SETTINGS_APP_URL_EMPTY_VALUE_MESSAGE (1932-1933)
  • GENERAL_SETTINGS_APP_URL_INVALID_MESSAGE (1923-1924)
  • GENERAL_SETTINGS_NAME_EMPTY_MESSAGE (1914-1915)
  • GENERAL_SETTINGS_APP_ICON_LABEL (1918-1918)
  • GENERAL_SETTINGS_APP_URL_LABEL (1919-1919)
  • GENERAL_SETTINGS_APP_URL_PLACEHOLDER_FETCHING (1921-1922)
  • GENERAL_SETTINGS_APP_URL_PLACEHOLDER (1920-1920)
  • GENERAL_SETTINGS_APP_URL_CHECKING_MESSAGE (1927-1928)
  • GENERAL_SETTINGS_APP_URL_AVAILABLE_MESSAGE (1929-1929)
  • GENERAL_SETTINGS_APP_URL_UNAVAILABLE_MESSAGE (1930-1931)
app/client/src/ce/actions/applicationActions.ts (6)
  • enableStaticUrl (322-330)
  • persistAppSlug (82-90)
  • resetAppSlugValidation (341-345)
  • validateAppSlug (92-99)
  • fetchAppSlugSuggestion (101-108)
  • disableStaticUrl (332-339)
app/client/src/ce/api/ApplicationApi.tsx (5)
  • enableStaticUrl (544-552)
  • persistAppSlug (522-533)
  • validateAppSlug (535-542)
  • fetchAppSlugSuggestion (560-566)
  • disableStaticUrl (554-558)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (57)
  • GitHub Check: perform-test / ci-test / ci-test (59)
  • GitHub Check: perform-test / ci-test / ci-test (58)
  • GitHub Check: perform-test / ci-test / ci-test (56)
  • GitHub Check: perform-test / ci-test / ci-test (43)
  • GitHub Check: perform-test / ci-test / ci-test (57)
  • GitHub Check: perform-test / ci-test / ci-test (33)
  • GitHub Check: perform-test / ci-test / ci-test (54)
  • GitHub Check: perform-test / ci-test / ci-test (52)
  • GitHub Check: perform-test / ci-test / ci-test (50)
  • GitHub Check: perform-test / ci-test / ci-test (44)
  • GitHub Check: perform-test / ci-test / ci-test (49)
  • GitHub Check: perform-test / ci-test / ci-test (51)
  • GitHub Check: perform-test / ci-test / ci-test (36)
  • GitHub Check: perform-test / ci-test / ci-test (37)
  • GitHub Check: perform-test / ci-test / ci-test (53)
  • GitHub Check: perform-test / ci-test / ci-test (45)
  • GitHub Check: perform-test / ci-test / ci-test (41)
  • GitHub Check: perform-test / ci-test / ci-test (42)
  • GitHub Check: perform-test / ci-test / ci-test (21)
  • GitHub Check: perform-test / ci-test / ci-test (55)
  • GitHub Check: perform-test / ci-test / ci-test (47)
  • GitHub Check: perform-test / ci-test / ci-test (48)
  • GitHub Check: perform-test / ci-test / ci-test (39)
  • GitHub Check: perform-test / ci-test / ci-test (32)
  • GitHub Check: perform-test / ci-test / ci-test (28)
  • GitHub Check: perform-test / ci-test / ci-test (16)
  • GitHub Check: perform-test / ci-test / ci-test (7)
  • GitHub Check: perform-test / ci-test / ci-test (38)
  • GitHub Check: perform-test / ci-test / ci-test (14)
  • GitHub Check: perform-test / ci-test / ci-test (35)
  • GitHub Check: perform-test / ci-test / ci-test (46)
  • GitHub Check: perform-test / ci-test / ci-test (8)
  • GitHub Check: perform-test / ci-test / ci-test (26)
  • GitHub Check: perform-test / ci-test / ci-test (40)
  • GitHub Check: perform-test / ci-test / ci-test (31)
  • GitHub Check: perform-test / ci-test / ci-test (27)
  • GitHub Check: perform-test / ci-test / ci-test (29)
  • GitHub Check: perform-test / ci-test / ci-test (34)
  • GitHub Check: perform-test / ci-test / ci-test (24)
  • GitHub Check: perform-test / ci-test / ci-test (25)
  • GitHub Check: perform-test / ci-test / ci-test (22)
  • GitHub Check: perform-test / ci-test / ci-test (20)
  • GitHub Check: perform-test / ci-test / ci-test (19)
  • GitHub Check: perform-test / ci-test / ci-test (12)
  • GitHub Check: perform-test / ci-test / ci-test (17)
  • GitHub Check: perform-test / ci-test / ci-test (18)
  • GitHub Check: perform-test / ci-test / ci-test (10)
  • GitHub Check: perform-test / ci-test / ci-test (23)
  • GitHub Check: perform-test / ci-test / ci-test (13)
  • GitHub Check: perform-test / ci-test / ci-test (0)
  • GitHub Check: perform-test / ci-test / ci-test (9)
  • GitHub Check: perform-test / ci-test / ci-test (11)
  • GitHub Check: perform-test / ci-test / ci-test (6)
  • GitHub Check: perform-test / ci-test / ci-test (2)
  • GitHub Check: perform-test / ci-test / ci-test (3)
  • GitHub Check: perform-test / ci-test / ci-test (4)
  • GitHub Check: perform-test / ci-test / ci-test (1)
🔇 Additional comments (8)
app/client/src/pages/AppIDE/components/AppSettings/components/GeneralSettings.tsx (8)

1-58: LGTM: Imports and regex are well-structured.

All imports are necessary for the static URL feature implementation. The APPLICATION_SLUG_REGEX pattern correctly enforces lowercase letters, digits, and hyphens for slugs.


86-119: LGTM: State management is well-organized.

The state variables properly track slug validation, modal state, and feature flag status. Initialization from application?.staticUrlSettings?.uniqueSlug correctly handles the optional chaining.


121-142: LGTM: Effects properly synchronize state.

The effects correctly handle state synchronization with appropriate guards. The !isSavingAppName check prevents race conditions during save operations.


144-195: LGTM: Modal handlers are well-implemented.

The handlers correctly distinguish between enabling static URLs for the first time and updating an existing slug. The reset logic in cancelSlugChange properly restores the original state.


227-249: LGTM: Slug change handler with proper validation flow.

The handler correctly normalizes the slug (lowercase, hyphen substitution) and validates client-side before dispatching server-side validation. This provides immediate feedback to users while ensuring uniqueness through the backend check.


251-305: LGTM: URL computation logic handles all scenarios correctly.

The modal slug computation properly handles three distinct cases: enabling static URLs for the first time, changing an existing static URL, and disabling static URLs. The fallback chain for page slugs (uniqueSlug || customSlug || slug) ensures resilience.


316-356: LGTM: Toggle and disable handlers are well-implemented.

The toggle handler correctly differentiates between disabling a persisted static URL (requiring confirmation) and disabling a newly toggled-on URL (immediate). The clipboard copy uses the modern navigator.clipboard API.


397-599: LGTM: Render section properly implements the static URL UI.

The component correctly gates the static URL feature behind the feature flag and shows appropriate validation states. The Apply button disable conditions comprehensively prevent invalid submissions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Enhancement New feature or request Frontend This label marks the issue or pull request to reference client code ok-to-test Required label for CI static-url Enables static and human-readable URLs for applications and pages.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants