React Router 7 Migration

This guide outlines the necessary steps to migrate a Hydrogen storefront with Remix to one with React Router 7. This will include:

  • Updating @shopify/hydrogen and @shopify/hydrogen-react to version 2025.7.0+
  • Updating @pack/hydrogen and @pack/react to 3.0.0 and 4.0.0, respectively
  • Replacing imports from @remix-run with react-router
  • All required code, config or import changes

Things to Consider

For every task under Manual Setup , there is a corresponding prompt under LLM Prompts that may be passed into an LLM for automating each task. These prompts have been tested internally using the IDE Cursor or the Claude Code extension for VS Code

If using Cursor, adjust the chat settings accordingly:

  1. Turn on Agent mode
  2. Turn on Auto-Run Mode to allow agent to write files without asking for permission each time'

If using Claude Code for VS Code, certain prompts may have the chat asking for permission for every bash command; in that case, approve each one as they come in. A note is left for the LLM in the prompt to hopefully prevent/limit this.

Manual Setup

Dependency Updates

  1. Update or add the following packages accordingly:
  • "@shopify/hydrogen": "2025.7.3"
  • "@shopify/hydrogen-react": "2025.7.2"
  • "@shopify/cli": "^3.88.1"
  • "@shopify/cli-hydrogen": "^11.1.6"
  • "react-router": "7.12.0"
  • "react-router-dom": "7.12.0"
  • "@react-router/dev": "7.12.0"
  • "@react-router/fs-routes": "7.12.0" (in devDependencies)
  • "@shopify/mini-oxygen": "^4.0.0"
  • "vite": "^6.2.4"
  • "@pack/hydrogen": "3.0.0"
  • "@pack/react": "4.0.0"
  1. Remove following packages:
  • "@remix-run/react"
  • "@shopify/remix-oxygen"
  • "@remix-run/dev"
  • "@remix-run/eslint-config"
  • "@remix-run/fs-routes"
  • "@remix-run/route-config"
  1. Update node version to 20, so:
  • In package.json, change: "node": ">=18.0.0" to "node": ">=20.0.0"
  • In .nvmrc, change v18 to v20
  1. Delete node_modules and package-lock.json
  2. Run npm install

React Router Config File

Add react-router.config.ts to the root of the repo:

import type {Config} from '@react-router/dev/config';
import {hydrogenPreset} from '@shopify/hydrogen/react-router-preset';

/**
 * This configuration uses the official Hydrogen preset to provide optimal
 * React Router settings for Shopify Oxygen deployment. The preset enables
 * validated performance optimizations while ensuring compatibility.
 */
export default {
  presets: [hydrogenPreset()],
  future: {
    // Disable middleware to use legacy context pattern (context.storefront vs context.get())
    // This is required until route files are migrated to use context.get(hydrogenContext.*)
    v8_middleware: false,
  },
} satisfies Config;

Server.ts Update

In server.ts:

  1. Replace import * as remixBuild from 'virtual:remix/server-build'; with import * as serverBuild from 'virtual:react-router/server-build';
  2. Update the import for createRequestHandler and getStorefrontHeader to be from @shopify/hydrogen/oxygen opposed to @shopify/remix-oxygen
  3. Replace build: remixBuild with build: serverBuild within createRequestHandler
  4. If testSession is not being passed into createPackClient do the following. Note, this is not a required step for RR7 migration, but to address the eslint error:
  • Import PackTestSession from @pack/hydrogen
  • Fetch packTestSession
const [cache, session, packSession, packTestSession] = await Promise.all([
  caches.open('hydrogen'),
  AppSession.init(request, [env.SESSION_SECRET]),
  PackSession.init(request, [env.SESSION_SECRET]),
  PackTestSession.init(request, [env.SESSION_SECRET]),
]);
  • Pass in packTestSession as testSession to `createPackClient

Vite Config

In vite.config.ts

  1. Replace import {vitePlugin as remix} from '@remix-run/dev'; with import {reactRouter} from '@react-router/dev/vite';
  2. Remove the remix({...}) plugin from the plugins array, and add reactRouter() instead
  3. Remove any remix related dependencies from the ssr.optimizeDeps.include and optimizeDeps.include arrays, e.g. @remix-run/dev/server-build
  4. Add react-router to the ssr.optimizeDeps.include array
  5. Add in this resolve config to the ssr object
resolve: {
  conditions: ['workerd', 'worker', 'browser'],
  externalConditions: ['workerd', 'worker'],
},
  1. Add this custom plugin above export default defineConfig
/**
 * Plugin to redirect vfile's Node.js imports to browser-compatible versions.
 * This fixes "No such module node:path" errors on Oxygen deployment.
 */
function vfileBrowserPlugin(): Plugin {
  return {
    name: 'vfile-browser',
    enforce: 'pre',
    resolveId(id, importer) {
      // Redirect vfile's internal imports to browser versions
      if (importer?.includes('node_modules/vfile/')) {
        // Get the vfile package root directory
        const vfileRoot = importer.substring(
          0,
          importer.indexOf('node_modules/vfile/') +
            'node_modules/vfile/'.length,
        );
        if (id === '#minpath') {
          return {id: vfileRoot + 'lib/minpath.browser.js'};
        }
        if (id === '#minproc') {
          return {id: vfileRoot + 'lib/minproc.browser.js'};
        }
        if (id === '#minurl') {
          return {id: vfileRoot + 'lib/minurl.browser.js'};
        }
      }
      return null;
    },
  };
}
  1. Add the import import type {Plugin} from 'vite'; then add vfileBrowserPlugin() to the plugins array
  2. If @pack/types is a dependency in package.json then ensure adding @pack/types to the ssr.optimizeDeps.include array
  3. Add server into root of defineConfig below optimizeDeps:
server: {
  headers: {
    // Allow Private Network Access from public origins (e.g., hosted iframe)
    'Access-Control-Allow-Private-Network': 'true',
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
    'Access-Control-Allow-Headers': '*',
  },
  allowedHosts: [],
}

Tsconfig Change

Swap all the lines in tsconfig.json with this instead:

{
  "include": [
    "env.d.ts",
    "app/**/*.ts",
    "app/**/*.tsx",
    "app/**/*.d.ts",
    "*.ts",
    "*.tsx",
    "*.d.ts",
    ".graphqlrc.ts",
    ".react-router/types/**/*"
  ],
  "exclude": ["node_modules", "dist", "build", "packages/**/dist/**/*"],
  "compilerOptions": {
    "lib": ["DOM", "DOM.Iterable", "ES2022"],
    "isolatedModules": true,
    "esModuleInterop": true,
    "jsx": "react-jsx",
    "moduleResolution": "Bundler",
    "resolveJsonModule": true,
    "module": "ES2022",
    "target": "ES2022",
    "strict": true,
    "allowJs": true,
    "forceConsistentCasingInFileNames": true,
    "skipLibCheck": true,
    "baseUrl": ".",
    "types": [
      "@shopify/oxygen-workers-types",
      "react-router",
      "@shopify/hydrogen/react-router-types",
      "vite/client",
      "@types/gtag.js",
      "@types/grecaptcha"
    ],
    "paths": {
      "~/_": ["app/_"]
    },
    "noEmit": true,
    "rootDirs": [".", "./.react-router/types"],
    "incremental": true,
    "composite": false,
    "verbatimModuleSyntax": true
  }
}

ESLint Update

In .eslintrc.cjs

  1. Remove @remix-run/eslint-config from the extends array
  2. Add import to the plugins array
  3. Add pathGroups array in the import/order object (below groups): pathGroups: [{pattern: '~/**', group: 'internal'}]

Route Type Pattern Changes

Find all the instances of ActionFunctionArgs, LoaderFunctionArgs, and MetaArgs in the codebase and do the following with the corresponding file:

  1. Import Route like this, where right of the last / is the name of the file itself. For example, if the file name is ($locale).products.$handle.tsx then the import for Route would look like import type {Route} from './+types/($locale).products.$handle’;
  2. Update ActionFunctionArgs to Route.ActionArgs; and LoaderFunctionArgs to Route.LoaderArgs
  3. Update each export const meta to be:
export const meta: Route.MetaFunction = ({matches}) => {
  return (
    getSeoMeta(...matches.map((match) => (match?.loaderData as any).seo)) || []
  );
};
  1. Remove the old type imports from the top of the file

Note: Do not make any additional import changes oustide this prompt, that will be handled in a following prompt


Import Updates

  1. In entry.client.ts
  • Replace the import import {RemixBrowser} from '@remix-run/react'; with import {HydratedRouter} from 'react-router/dom';
  • Replace <RemixBrowser /> with <HydratedRouter />
  1. In entry.server.ts
  • Replace import {RemixServer} from '@remix-run/react'; with import {ServerRouter} from 'react-router';
  • Replace import type {EntryContext} from '@shopify/remix-oxygen'; with import type {EntryContext} from 'react-router';
  • Replace import type {AppLoadContext} from '@shopify/remix-oxygen'; with import type {HydrogenRouterContextProvider} from '@shopify/hydrogen';
  • Replace the line remixContext: EntryContext with reactRouterContext: EntryContext
  • Replace <RemixServer context={remixContext} url={request.url} /> with <ServerRouter context={reactRouterContext} url={request.url} />
  • Replace the line context: AppLoadContext with context: HydrogenRouterContextProvider
  1. In routes.ts
  • Replace import {flatRoutes} from '@remix-run/fs-routes'; with import {flatRoutes} from '@react-router/fs-routes';
  • Replace import type {RouteConfig} from '@remix-run/route-config'; with import type {RouteConfig} from '@react-router/dev/routes';
  • Replace export default hydrogenRoutes([...(await flatRoutes())]) satisfies RouteConfig; with
export default hydrogenRoutes([
  ...(await flatRoutes()),
  // Manual route definitions can be added to this array, in addition to or instead of using the `flatRoutes` file-based routing convention.
  // See https://reactrouter.com/api/framework-conventions/routes.ts#routests
]) satisfies RouteConfig;
  1. Find all instances where components or types are imported from @shopify/remix-oxygen and change the import to be from react-router instead
  • For example: import type {AppLoadContext, ActionFunctionArgs} from '@shopify/remix-oxygen'; becomes import type {AppLoadContext, ActionFunctionArgs} from 'react-router';
  • This includes data and redirect, for example: import {data as dataWithOptions, redirect} from '@shopify/remix-oxygen'; becomes import {data as dataWithOptions, redirect} from 'react-router';
  1. Find all instances where components or types are imported from @remix-run/react, and change the import to be from react-router instead

env.d.ts File

In env.d.ts:

  1. First if there is no env.d.ts but instead remix.env.d.ts, rename remix.env.d.ts to env.d.ts
  2. Replace all the /// <reference />'s at the top with these:
/// <reference types="vite/client" />
/// <reference types="react-router" />
/// <reference types="@shopify/oxygen-workers-types" />
/// <reference types="@shopify/hydrogen/react-router-types" />
  1. Replace declare module '@shopify/remix-oxygen' with declare module 'react-router'

Remove displayName Definition From All Route Files

For all the app/routes files, if a displayName is defined:

  • Replace the data-comp attribute values from ComponentName.displayName to the actual display name. For example, data-comp={ProductRoute.displayName} becomes data-comp="ProductRoute"
  • Remove the .displayName defintion at the bottom

Misc

  1. If the DEFAULT_STOREFRONT_API_VERSION constant exists, update it to be 2025-07; if not, find where ShopifyProvider is rendered, and update the fallback for storefrontApiVersion to be 2025-07
  2. In Link.tsx
  • Update RemixLink to be ReactRouterLink; and RemixLinkProps to be ReactRouterLinkProps
  • Update the comment link to the docs to use the url https://api.reactrouter.com/v7/functions/react_router.Link.html
  • Change remix property to react router property
  1. Add .react-router to .gitignore
  2. Remove uuid from package.json and from vite.config.ts if it exists; then find all instances where uuid is being imported, e.g. import {v4 as uuidv4} from 'uuid';, then do the following. At the end run npm install:
  • Replace the use of uuidv4() with crypto.randomUUID()
  • Remove the import from the top
  1. Find where useMatches is being used and change any match using .data to .loaderData
  2. In useRootLoaderData, update type RootLoaderData to be: export type RootLoaderData = Awaited<ReturnType<typeof loader>>;; then remove the SerializeFrom import
  3. In Scripts.tsx, remove the line IMPORTANT: Third party scripts rendered directly, i.e. as <script> tags, will likely cause hydration errors as a gotcha of Remix. Use the useLoadScript hook to avoid this issue. if it exists
  4. In server.ts, change the text Create a Remix request handler to Create a React Router request handler
  5. In README.md, change any reference to Remix to React Router
  6. If app/lib/admin-api/admin.ts and app/lib/admin-api/utils/graphql.ts exists, change any reference to Remix to React Router

LLM Prompts

Dependency Updates

1. Update or add the following packages accordingly:

- "@shopify/hydrogen": "2025.7.3"
- "@shopify/hydrogen-react": "2025.7.2"
- "@shopify/cli": "^3.88.1" (move to devDependencies)
- "@shopify/cli-hydrogen": "^11.1.6" (move to devDependencies)
- "react-router": "7.12.0"
- "react-router-dom": "7.12.0"
- "@react-router/dev": "7.12.0" (in devDependencies)
- "@react-router/fs-routes": "7.12.0" (in devDependencies)
- "@shopify/mini-oxygen": "^4.0.0" (move to devDependencies)
- "vite": "^6.2.4"
- "@pack/hydrogen": "3.0.0"
- "@pack/react": "4.0.0"

2. Remove following packages:

- "@remix-run/react"
- "@shopify/remix-oxygen"
- "@remix-run/dev"
- "@remix-run/eslint-config"
- "@remix-run/fs-routes"
- "@remix-run/route-config"

3. Update node version to 20, so:
- In `package.json`, change: `"node": ">=18.0.0"` to `"node": ">=20.0.0"`
- In `.nvmrc`, change `v18` to `v20`

4. Delete `node_modules` and `package-lock.json`
5. Run `npm install`

React Router Config File

Add `react-router.config.ts` to the root of the repo:

/* Code starts below. Do not include this line */
import type {Config} from '@react-router/dev/config';
import {hydrogenPreset} from '@shopify/hydrogen/react-router-preset';

/**
 * This configuration uses the official Hydrogen preset to provide optimal
 * React Router settings for Shopify Oxygen deployment. The preset enables
 * validated performance optimizations while ensuring compatibility.
 */
export default {
  presets: [hydrogenPreset()],
  future: {
    // Disable middleware to use legacy context pattern (context.storefront vs context.get())
    // This is required until route files are migrated to use context.get(hydrogenContext.*)
    v8_middleware: false,
  },
} satisfies Config;
/* Code ends above. Do not include this line */

Server.ts Update

In `server.ts`:

1. Replace `import * as remixBuild from 'virtual:remix/server-build';` with `import * as serverBuild from 'virtual:react-router/server-build';`
2. Update the import for `createRequestHandler` and `getStorefrontHeader` to be from `@shopify/hydrogen/oxygen` opposed to `@shopify/remix-oxygen`
3. Replace `build: remixBuild` with `build: serverBuild` within `createRequestHandler`
4. If `testSession` is not being passed into `createPackClient`:
- Import `PackTestSession` from `@pack/hydrogen`
- Fetch `packTestSession`
/* Code starts below. Do not include this line */
const [cache, session, packSession, packTestSession] = await Promise.all([
  caches.open('hydrogen'),
  AppSession.init(request, [env.SESSION_SECRET]),
  PackSession.init(request, [env.SESSION_SECRET]),
  PackTestSession.init(request, [env.SESSION_SECRET]),
]);
/* Code ends above. Do not include this line */
- Pass in `packTestSession` as `testSession` to `createPackClient

Vite Config

In `vite.config.ts`

1. Replace `import {vitePlugin as remix} from '@remix-run/dev';` with `import {reactRouter} from '@react-router/dev/vite';`
2. Remove the `remix({...})` plugin from the `plugins` array, and add `reactRouter()` instead
3. Remove any `remix` related dependencies from the `ssr.optimizeDeps.include` and `optimizeDeps.include` arrays, e.g. `@remix-run/dev/server-build`
4. Add `react-router` to the `ssr.optimizeDeps.include` array
5. Add in this `resolve` config to the `ssr` object

/* Code starts below. Do not include this line */
resolve: {
  conditions: ['workerd', 'worker', 'browser'],
  externalConditions: ['workerd', 'worker'],
},
/* Code ends above. Do not include this line */

6. Add this custom plugin above `export default defineConfig`

/* Code starts below. Do not include this line */
/**
 * Plugin to redirect vfile's Node.js imports to browser-compatible versions.
 * This fixes "No such module node:path" errors on Oxygen deployment.
 */
function vfileBrowserPlugin(): Plugin {
  return {
    name: 'vfile-browser',
    enforce: 'pre',
    resolveId(id, importer) {
      // Redirect vfile's internal imports to browser versions
      if (importer?.includes('node_modules/vfile/')) {
        // Get the vfile package root directory
        const vfileRoot = importer.substring(
          0,
          importer.indexOf('node_modules/vfile/') +
            'node_modules/vfile/'.length,
        );
        if (id === '#minpath') {
          return {id: vfileRoot + 'lib/minpath.browser.js'};
        }
        if (id === '#minproc') {
          return {id: vfileRoot + 'lib/minproc.browser.js'};
        }
        if (id === '#minurl') {
          return {id: vfileRoot + 'lib/minurl.browser.js'};
        }
      }
      return null;
    },
  };
}
/* Code ends above. Do not include this line */

7. Add the import `import type {Plugin} from 'vite';` then add `vfileBrowserPlugin()` to the `plugins` array
8. If `@pack/types` is a dependency in `package.json` then ensure adding `@pack/types` to the `ssr.optimizeDeps.include` array
9. Add `server` into root of `defineConfig` below `optimizeDeps`:
/* Code starts below. Do not include this line */
server: {
  headers: {
    // Allow Private Network Access from public origins (e.g., hosted iframe)
    'Access-Control-Allow-Private-Network': 'true',
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
    'Access-Control-Allow-Headers': '*',
  },
  allowedHosts: [],
}
/* Code ends above. Do not include this line */

Tsconfig Change

Swap all the lines in `tsconfig.json` with this instead:

/* Code starts below. Do not include this line */
{
  "include": [
    "env.d.ts",
    "app/**/*.ts",
    "app/**/*.tsx",
    "app/**/*.d.ts",
    "*.ts",
    "*.tsx",
    "*.d.ts",
    ".graphqlrc.ts",
    ".react-router/types/**/*"
  ],
  "exclude": ["node_modules", "dist", "build", "packages/**/dist/**/*"],
  "compilerOptions": {
    "lib": ["DOM", "DOM.Iterable", "ES2022"],
    "isolatedModules": true,
    "esModuleInterop": true,
    "jsx": "react-jsx",
    "moduleResolution": "Bundler",
    "resolveJsonModule": true,
    "module": "ES2022",
    "target": "ES2022",
    "strict": true,
    "allowJs": true,
    "forceConsistentCasingInFileNames": true,
    "skipLibCheck": true,
    "baseUrl": ".",
    "types": [
      "@shopify/oxygen-workers-types",
      "react-router",
      "@shopify/hydrogen/react-router-types",
      "vite/client",
      "@types/gtag.js",
      "@types/grecaptcha"
    ],
    "paths": {
      "~/*": ["app/*"]
    },
    "noEmit": true,
    "rootDirs": [".", "./.react-router/types"],
    "incremental": true,
    "composite": false,
    "verbatimModuleSyntax": true
  }
}
/* Code ends above. Do not include this line */

ESLint Update

In `.eslintrc.cjs`

1. Remove `@remix-run/eslint-config` from the `extends` array
2. Add `import` to the `plugins` array
3. Add `pathGroups` array in the `import/order` object (below `groups`): `pathGroups: [{pattern: '~/**', group: 'internal'}]`

Route Type Pattern Changes

Find all the instances of `ActionFunctionArgs`, `LoaderFunctionArgs`, and `MetaArgs` in the codebase and do the following with the corresponding file:

1. Import `Route` like this, where right of the last `/` is the name of the file itself. For example, if the file name is `($locale).products.$handle.tsx` then the import for `Route` would look like `import type {Route} from './+types/($locale).products.$handle’;`
 - Make sure the route import comes after the `'~/*'` imports with a line in between (i.e. follows eslint import order rule. Same block as sibling imports, i.e. `'./*'`)
2. Update `ActionFunctionArgs` to `Route.ActionArgs`; and `LoaderFunctionArgs` to `Route.LoaderArgs`
3. Update each `export const meta` to be:
/* Code starts below. Do not include this line */
export const meta: Route.MetaFunction = ({matches}) => {
  return (
    getSeoMeta(...matches.map((match) => (match?.loaderData as any).seo)) || []
  );
};
/* Code ends above. Do not include this line */
4. Remove the unused `ActionFunctionArgs`, `LoaderFunctionArgs`, and `MetaArgs` imports from the top of the file

Notes:
1. Do not make any additional import changes oustide this prompt
2. You do not need to ask for permission for every bash command

Import Updates

1. In `entry.client.ts`

- Replace the import `import {RemixBrowser} from '@remix-run/react';` with `import {HydratedRouter} from 'react-router/dom';`
- Replace `<RemixBrowser />` with `<HydratedRouter />`

2. In `entry.server.ts`

- Replace `import {RemixServer} from '@remix-run/react';` with `import {ServerRouter} from 'react-router';`
- Replace `import type {EntryContext} from '@shopify/remix-oxygen';` with `import type {EntryContext} from 'react-router';`
- Replace `import type {AppLoadContext} from '@shopify/remix-oxygen';` with `import type {HydrogenRouterContextProvider} from '@shopify/hydrogen';`
- Replace the line `remixContext: EntryContext` with `reactRouterContext: EntryContext`
- Replace `<RemixServer context={remixContext} url={request.url} />` with `<ServerRouter context={reactRouterContext} url={request.url} />`
- Replace the line `context: AppLoadContext` with `context: HydrogenRouterContextProvider`

3. In `routes.ts`

- Replace `import {flatRoutes} from '@remix-run/fs-routes';` with `import {flatRoutes} from '@react-router/fs-routes';`
- Replace `import type {RouteConfig} from '@remix-run/route-config';` with `import type {RouteConfig} from '@react-router/dev/routes';`
- Replace `export default hydrogenRoutes([...(await flatRoutes())]) satisfies RouteConfig;` with

/* Code starts below. Do not include this line */
export default hydrogenRoutes([
 ...(await flatRoutes()),
 // Manual route definitions can be added to this array, in addition to or instead of using the `flatRoutes` file-based routing convention.
 // See https://reactrouter.com/api/framework-conventions/routes.ts#routests
]) satisfies RouteConfig;
/* Code ends above. Do not include this line */

4. Find all instances in the codebase where components or types are imported from `@shopify/remix-oxygen` and change the import to be from `react-router` instead
- For example: `import type {AppLoadContext, ActionFunctionArgs} from '@shopify/remix-oxygen';` becomes `import type {AppLoadContext, ActionFunctionArgs} from 'react-router';`
- This includes `data` and `redirect`, for example: `import {data as dataWithOptions, redirect} from '@shopify/remix-oxygen';` becomes `import {data as dataWithOptions, redirect} from 'react-router';`
5. Find all instances in the codebase where components or types are imported from `@remix-run/react`, and change the import to be from `react-router` instead

Notes:
1. Do not make any additional import changes oustide this prompt
2. You do not need to ask for permission for every bash command

env.d.ts File

In `env.d.ts`:

1. First if there is no `env.d.ts` but instead `remix.env.d.ts`, rename `remix.env.d.ts` to `env.d.ts`
2. Replace all the `/// <reference />`'s at the top with these:

/* Code starts below. Do not include this line */
/// <reference types="vite/client" />
/// <reference types="react-router" />
/// <reference types="@shopify/oxygen-workers-types" />
/// <reference types="@shopify/hydrogen/react-router-types" />
/* Code ends above. Do not include this line */

3. Replace `declare module '@shopify/remix-oxygen'` with `declare module 'react-router'`

Remove displayName Definition From All Route Files

For all the `app/routes` files, if a `displayName` is defined:

- Replace the `data-comp` attribute values from `ComponentName.displayName` to the actual display name. For example, `data-comp={ProductRoute.displayName}` becomes `data-comp="ProductRoute"`
- Remove the `.displayName` defintion at the bottom

Misc

1. If the `DEFAULT_STOREFRONT_API_VERSION` constant exists, update it to be `2025-07`; if not, find where `ShopifyProvider` is rendered, and update the fallback for `storefrontApiVersion` to be `2025-07`
2. In `Link.tsx`

- Update `RemixLink` to be `ReactRouterLink`; and `RemixLinkProps` to be `ReactRouterLinkProps`
- Update the comment link to the docs to use the url `https://api.reactrouter.com/v7/functions/react_router.Link.html`
- Change `remix property` to `react router property`

3. Add `.react-router` to `.gitignore`
4. Remove `uuid` from `package.json` and from `vite.config.ts` if it exists; then find all instances where `uuid` is being imported, e.g. `import {v4 as uuidv4} from 'uuid';`, then do the following. At the end run `npm install`:

- Replace the use of `uuidv4()` with `crypto.randomUUID()`
- Remove the import from the top

5. Find where `useMatches` is being used and change any match using `.data` to `.loaderData`
6. In `useRootLoaderData`, update type `RootLoaderData` to be: `export type RootLoaderData = Awaited<ReturnType<typeof loader>>;`; then remove the `SerializeFrom` import
7. In `Scripts.tsx`, remove the line `IMPORTANT: Third party scripts rendered directly, i.e. as <script> tags, will likely cause hydration errors as a gotcha of Remix. Use the useLoadScript hook to avoid this issue.` if it exists
8. In `server.ts`, change the text `Create a Remix request handler` to `Create a React Router request handler`
9. In `README.md`, change any reference to `Remix` to `React Router`
10. If `app/lib/admin-api/admin.ts` and `app/lib/admin-api/utils/graphql.ts` exists, change any reference to `Remix` to `React Router`

Notes:
1. You do not need to ask for permission for every bash command

Was this page helpful?