ZuploZuplo
LoginSign Up
  • Documentation
  • API Reference

Dev Portal Migration Guide

This guide walks you through migrating your existing documentation from the current Dev Portal to the new Dev Portal powered by Zudoku. Follow these steps sequentially for a smooth transition.

Before you begin

It's important to note that this migration is to a completely new developer portal. As such, there could be things that are different or don't map exactly to the old developer portal. This new developer portal is more powerful and flexible, but it may require some adjustments to your existing content and configuration.

A few things to keep in mind before starting the migration:

Separate domain for Dev Portal

New Dev Portals run on their own dedicated domain instead of a /docs path under your API. You must create a redirect route on /docs to maintain existing links. You can use the Legacy Dev Portal Handler to achieve this.

Builder plans have been automatically upgraded to include two custom domains instead of one. This allows you to have a custom domain for both your API and your developer portal.

Authentication changes

Not all authentication providers from the old Dev Portal are supported in the new Developer Portal. The previous "external" provider isn't supported. If you were using that provider, you will need to switch to a supported provider such as Auth0 or implement a custom authentication solution.

Other considerations

  • Theming: Custom CSS from the old Dev Portal isn't directly supported. You will need to reapply any custom styles using the new theming options in Zudoku.
  • Navigation: Navigation in the new developer portal is much more flexible, but this does mean you will likely need to update your navigation structure.
  • Dark Mode: The new Dev Portal has built-in support for dark mode, which wasn't available in the old portal. You may want to use a different logo for dark mode.

Test in a preview environment

Don't perform the migration directly on your production environment. Instead, create a preview environment to test the migration. This allows you to verify that everything works as expected before making the changes live.

Things to test in the preview environment:

  • Navigation between pages
  • Authentication flows
  • API reference rendering
  • API Playground functionality
  • Custom theming and styles

Migration options

There are three ways to migrate your existing Dev Portal to the new version. Choose the one that best fits your needs:

  • Migrate in the portal (for simple setups)
  • Quick migration with CLI (for most projects)
  • Manual migration process (for full control)

Migrate in the portal

If you have a simple Dev Portal setup and prefer to migrate directly in the Zuplo Portal, you can use the built-in migration tool by opening the config/dev-portal.json file in the Zuplo Portal and clicking the Migrate to Zudoku button at the top of the editor. This will automatically create the necessary files and move your existing configuration and markdown files to the new format.

Quick migration with CLI

For most projects, you can use the Zuplo CLI to automate the migration process:

TerminalCode
npx zuplo source migrate dev-portal

This command will automatically:

  • Create the required directory structure
  • Generate necessary configuration files
  • Migrate your existing dev portal configuration
  • Move markdown files to the correct location

See the Source Commands documentation for more details and options.

If you prefer to understand each step or need more control over the migration process, continue with the manual migration steps below.

Manual migration process

  1. Prepare Your Environment

    Clone your existing Zuplo project locally. We recommend trying this in a branch and deploying to a preview environment first.

    TerminalCode
    git clone https://github.com/my-org/my-api cd my-api git checkout -b dev-portal-migration

    Currently, this migration must be done locally. It cannot be done in the Zuplo Portal.

  2. Create Directory Structure

    Set up your new directory structure by creating the following files and folders:

    • Create docs/zudoku.config.ts as an empty file, the contents will be added later.
    • Create docs/package.json as an empty file, the contents will be added later.
    • Create docs/tsconfig.json as an empty file, the contents will be added later.
    • Create a directory docs/pages for your markdown files
    • Create a directory docs/public for images and other static assets

    Once these files are created your directory structure should look like this. Note, that the old dev portal files are still in place. You will delete them later.

    Code
    my-api/ ├─ config/ │ ├─ dev-portal.json # <- Your existing dev-portal.json │ ├─ routes.oas.json │ ├─ policies.json ├─ docs/ │ ├─ sidebar.json # <- Your existing sidebar.json │ ├─ theme.css # <- Your existing theme.css │ ├─ zudoku.config.ts │ ├─ package.json │ ├─ tsconfig.json │ ├─ pages/ │ │ ├─ doc.md # <- Your existing markdown files │ ├─ public/ # <- Your images and other static assets ├─ .gitignore ├─ package.json ├─ tsconfig.json ├─ README.md
  3. Update TypeScript Configuration File

    If you haven't already, create a tsconfig.json file in the docs folder and update the file with the following content.

    docs/tsconfig.json
    { "compilerOptions": { "target": "ES2022", "lib": ["ESNext", "DOM", "DOM.Iterable", "WebWorker"], "module": "ESNext", "moduleResolution": "Bundler", "useDefineForClassFields": true, "skipLibCheck": true, "skipDefaultLibCheck": true, "resolveJsonModule": true, "isolatedModules": true, "useUnknownInCatchVariables": false, "types": ["zudoku/client"], "jsx": "react-jsx" } }
  4. Update package.jsonFile

    If you haven't already, create a package.json file in the docs folder and update the file with the following content.

    docs/package.json
    { "name": "docs", "version": "0.1.0", "type": "module", "private": true, "scripts": { "dev": "zudoku dev --zuplo", "build": "zudoku build --zuplo" }, "dependencies": { "react": ">19.0.0", "react-dom": ">19.0.0", "zudoku": "^0.39" }, "devDependencies": { "typescript": "^5", "@types/node": "^22", "@types/react": "^19", "@types/react-dom": "^19" } }
  5. Update Root Package.json

    Add the workspaces configuration to your root package.json file. Optionally, add a new script docs to run the dev portal.

    package.json
    { "name": "my-api", "version": "0.1.0", "scripts": { "dev": "zuplo dev", "test": "zuplo test", "docs": "npm run dev --workspace docs" }, "workspaces": { "packages": ["docs"] } }
  6. Migrate Dev Portal Configuration

    If you haven't already done so, create a new zudoku.config.ts file in the docs directory to replace your existing dev-portal.json.

    Here's how several fields map from old to new format. See the configuration documentation for a complete list of options.

    Old (dev-portal.json)New (zudoku.config.ts)
    pageTitlesite.title
    faviconUrlmetadata.favicon
    enableAuthenticationImplied by presence of authentication property
    authentication.providerauthentication.type
    authentication.authorityProvider-specific properties
    (from sidebar.json)navigation array

    Example configuration:

    docs/zudoku.config.ts
    import type { ZudokuConfig } from "zudoku"; const config: ZudokuConfig = { site: { title: "My API", // Was pageTitle in the old format }, metadata: { favicon: "https://www.example.org/favicon.ico", // Was faviconUrl }, navigation: [ { type: "category", label: "Documentation", items: [ "introduction", // Using shorthand for docs "other-example", ], }, { type: "link", to: "/api", label: "API Reference" }, ], redirects: [{ from: "/", to: "/introduction" }], apis: [ { type: "file", input: "../config/routes.oas.json", path: "/api", }, ], apiKeys: { // Enable API Key Management, disabled by default enabled: true, }, authentication: { type: "auth0", // Was provider in the old format domain: process.env.ZUPLO_PUBLIC_AUTH0_DOMAIN, clientId: process.env.ZUPLO_PUBLIC_AUTH0_CLIENT_ID, }, }; export default config;

    Environment variables are now referenced using process.env instead of $env().

  7. Migrate Sidebar Configuration

    Move your sidebar configuration from sidebar.json to the navigation array in zudoku.config.ts:

    Old format (sidebar.json):

    Code
    [ { "type": "category", "label": "Getting Started", "items": ["introduction", "quickstart"] }, { "type": "doc", "id": "api-reference" } ]

    New format (in zudoku.config.ts):

    Code
    navigation: [ { type: "category", label: "Documentation", items: [ { type: "category", label: "Getting Started", items: [ { type: "doc", file: "introduction", // Note: no path prefix needed }, { type: "doc", file: "quickstart", }, ], }, "authentication", // Directly reference doc files ], }, { type: "link", to: "/api", label: "API Reference", }, ];
  8. Move Markdown Files

    Move your markdown files to the docs/pages directory. The front matter format remains largely the same:

    Code
    --- title: Introduction sidebar_label: Intro description: Introduction to our API ---
  9. Set Up Images and Assets

    Create a docs/public directory for your images and other static assets. See the documentation for more information on how to use static files in the new dev portal.

  10. Install Dependencies

    Run npm install from your project root to install all dependencies for both your API and documentation.

  11. Test Locally

    Start the dev portal locally with npm run docs and verify that:

    • All pages load correctly
    • Authentication works (if using it)
    • All links between pages work
    • API reference section loads your OpenAPI definitions
    • Images and assets display properly
  12. Delete Legacy Files

    After confirming everything works, delete these files:

    • /config/dev-portal.json
    • /docs/sidebar.json
    • /docs/theme.css

    It is critical that you delete the config/dev-portal.json file after completing the migration. If that file is not deleted, the Zuplo build system will use the legacy dev portal.

  13. Deploy and Verify

    Deploy your changes by either pushing to a git branch or by running npx zuplo deploy. After the deployment has completed, perform these final checks:

    • Test all site navigation paths
    • Verify authentication flows work correctly
    • Check API reference documentation renders
    • Test across different browsers and devices
    • Verify custom styling and theming is applied correctly

Theming

For instructions on theming the dev portal, see Colors & Theme and Fonts.

Redirect legacy URLs

The previous Dev Portal was hosted on a path on the same domains your Zuplo API (i.e. https://api.example.com/docs). The new Dev Portal is hosted on its own domain and can have its own custom domain (i.e. https://docs.example.com). Learn more about setting up custom domains in the Custom Domains documentation.

If you were using the previous Dev Portal, you can redirect all requests from the legacy path to the new domain using the Legacy Dev Portal Handler. This allows you to maintain backwards compatibility for users who may have bookmarked or linked to the old Dev Portal URL.

Setup Instructions

  1. Create a New Routes File: In your Zuplo project, create a new OpenAPI file called legacy.oas.json (or any name you prefer).

  2. Add a Route: Inside this file, add a route that matches the legacy path and redirects to the new Dev Portal domain. You must set the path to the path used by the previous Dev Portal, such as /docs(.*). It's important not to make the route /docs(.*) not /docs/(.*) in order to also match the root path /docs.

    For example:

    Code
    { "openapi": "3.1.0", "info": { "version": "1.0.0", "title": "Dev Portal Redirect" }, "paths": { "/docs(.*)": { "x-zuplo-path": { "pathMode": "url-pattern" }, "get": { "summary": "Redirect", "description": "Redirect to the new Dev Portal domain", "x-zuplo-route": { "corsPolicy": "none", "handler": { "export": "legacyDevPortalHandler", "module": "$import(@zuplo/runtime)", "options": { "mode": "redirect" } }, "policies": { "inbound": [] } }, "operationId": "dev-portal-redirect" } } } }

After you redeploy your Zuplo project, whenever the user navigates to the legacy developer portal paths, they will be redirected to the new Dev Portal domain.

For more detailed information about the handler, including how to configure proxy mode to keep your developer portal on the same domain, see the Legacy Dev Portal Handler documentation.

Additional redirects

Your new developer portal may also change other paths. To create redirects for specific docs or other path in your new Dev Portal, we recommend using the redirects configuration in the zudoku.config.ts file. This allows you to specify multiple redirects easily. For more information, see the Redirects section in the configuration docs

Troubleshooting

If you encounter issues during migration, check these common problems:

  • Missing dependencies: Ensure you've run npm install from the project root.
  • Authentication issues: Verify your environment variables are correctly set and authentication is properly configured.
  • Sidebar not showing: Check your sidebar configuration in zudoku.config.ts and make sure file IDs match your markdown files.
  • Images not loading: Confirm image paths have been updated to point to the new location.
  • Environment variables not working: Use process.env.VARIABLE_NAME instead of $env(VARIABLE_NAME).
Edit this page
Last modified on March 23, 2026
On this page
  • Before you begin
    • Separate domain for Dev Portal
    • Authentication changes
    • Other considerations
    • Test in a preview environment
  • Migration options
    • Migrate in the portal
    • Quick migration with CLI
    • Manual migration process
  • Theming
  • Redirect legacy URLs
    • Setup Instructions
    • Additional redirects
  • Troubleshooting
JSON
JSON
JSON
TypeScript
JSON
TypeScript
Markdown
JSON