Migrate a Dashboard Page Extension

Add a dashboard page extension to your new Wix CLI project as part of migrating an app from the legacy Wix CLI.

Folder structure

Legacy pathNew path
src/dashboard/pages/<name>/page.jsonsrc/extensions/dashboard/pages/<name>/<name>.extension.ts
src/dashboard/pages/<name>/page.tsxsrc/extensions/dashboard/pages/<name>/<name>.tsx

Note: <name> is your extension's folder name in the legacy project. The new folder and files use the same name.

A legacy dashboard page's files can also sit directly in src/dashboard/pages/ instead of in a subfolder. Migrate it like any other page. Since it has no folder to take a name from, choose a <name> for it, for example a slugified version of its title.

Step 1 | Copy and rename the files

In the new project:

  1. Create the folder src/extensions/dashboard/pages/<name>/.
  2. From the legacy project's src/dashboard/pages/<name>/ folder, or from src/dashboard/pages/ if the extension has no subfolder, copy page.tsx into the new folder, and rename it to <name>.tsx.
  3. Copy any asset files the extension imports into the new folder.

Don't copy the legacy page.json file. You recreate its values in <name>.extension.ts.

Step 2 | Adapt the code to the new project

In <name>.tsx:

  1. Update any imports as needed, to use the new paths.
  2. Replace any import from the legacy page.json, such as import { id } from './page.json', with the value itself. The JSON file isn't copied to the new project. The same applies to an import from another extension's legacy config file, such as a modal's modal.json.
  3. If the component imports wix.config.json, for example to read appId, replace the import with the value. The new project has no wix.config.json.
  4. If the component imports shared code from outside the extension's folder, such as components or hooks under src/dashboard/, copy that code into the new project at the same path, and update the relative imports from the component's new location. See Add the extension to the new project in the main migration guide.
  5. If the component calls a web method or an HTTP function, replace the call. Fixing the import path isn't enough, because the legacy backend code doesn't exist in that form after the migration. See Migrate from Web Methods to HTTP Endpoints or Migrate from HTTP Functions to HTTP Endpoints.

Note: Asset imports such as import logo from './logo.svg' resolve to a URL string in the new project, as they do in your legacy project, so they need no change. An import with the ?url suffix also works.

Step 3 | Create the extension file

In the new project:

  1. In src/extensions/dashboard/pages/<name>/, create <name>.extension.ts.

  2. Add the following code, and set each field to the value the table below specifies:

    Copy
    FieldSource in legacy projectWhat to specify
    idid in page.jsonCopy source as is
    titletitle in page.jsonCopy source as is
    routePathNoneThe page's current route, which keeps the URL the page already has, or a slug of your choice. See Find the current route.
    componentNonePath to <name>.tsx, relative to src/
    prioritysidebar.priority in page.jsonIf your legacy page.json sets it, add priority and copy the number as is, to preserve the sidebar order. See Sidebar order (priority).

Important: The id must match the value from the legacy page.json. Otherwise, the new entry is treated as a separate extension instead of a continuation of the legacy one.

Find the current route

A legacy page.json has no routePath field. The legacy CLI derives each page's route from where the page's files sit in src/dashboard/pages/:

  • A page whose files sit directly in src/dashboard/pages/ has an empty route. This is the page created with your app.
  • A page in a subfolder has the subfolder's path as its route. Nested subfolders make a longer route.

For example, a page in src/dashboard/pages/products/ has the route products, and a page in src/dashboard/pages/products/analytics/ has the route products/analytics.

Important: The page created with your app has an empty routePath, which is what makes it the page your app opens by default. Specify routePath: '' to keep that. An empty route is a valid value, and the new project's own starter page ships with one, so this page keeps the URL it already had.

Step 4 | Register the extension

In the new project, in src/extensions.ts:

  1. Import the extension:

    Copy
  2. Add a .use() call for it to the app() chain, on its own line:

    Copy

Step 5 | Return to the main migration guide

Return to Install the extension's dependencies in the main migration guide.

Last updated: 10 November 2026

Did this help?