mirror of
https://github.com/Dvorinka/Devour.git
synced 2026-06-03 20:13:03 +00:00
231 lines
181 KiB
JSON
231 lines
181 KiB
JSON
{
|
|
"id": "9b9e0a1045a4d61ba968d0bc",
|
|
"source": "remix:does",
|
|
"type": "html",
|
|
"title": "Future Flags | Remix",
|
|
"content": "DocsBlogResourcesReact Router v7 has been released. View the docsDocsBlogResourcesView code on GitHubChat on DiscordReact Router v7 has been released. View the docsFuture FlagsGetting StartedQuick Start (5m) Tutorial (30m) Upgrading to v2 Community Future Flags Changelog Discussion TopicsIntroduction, Technical Explanation Runtimes, Adapters, Templates, and Deployment Route Configuration Fullstack Data Flow Server vs. Client Code Execution React Router Progressive Enhancement Pending UI State Management Network Concurrency Management Form vs. fetcher Hot Module Replacement Form Resubmissions File Conventions.client modules .server modules Asset Imports entry.client entry.server root Route File Naming vite.config.ts Route Moduleaction clientAction clientLoader Component ErrorBoundary handle headers HydrateFallback links loader meta shouldRevalidate ComponentsAwait Form Link Links LiveReload Meta NavLink Outlet PrefetchPageLinks Scripts ScrollRestoration HooksuseActionData useAsyncError 🆕useAsyncValue 🆕useBeforeUnload useBlocker useFetcher useFetchers useFormAction useHref useLoaderData useLocation useMatches useNavigate useNavigation useNavigationType useOutlet useOutletContext useParams unstable_usePrompt useResolvedPath useRevalidator 🆕useRouteError 🆕useRouteLoaderData useSearchParams useSubmit useViewTransitionState UtilitiesCookies createRemixStub data defer isRouteErrorResponse json unstable_parseMultipartFormData redirect redirectDocument replace Sessions unstable_createFileUploadHandler unstable_createMemoryUploadHandler StylingCSS Bundling Regular CSS CSS Imports CSS in JS CSS Modules PostCSS Tailwind Vanilla Extract Other API@remix-run/dev CLI 🆕@remix-run/{adapter} @remix-run/serve create-remix (CLI) @remix-run/node @remix-run/testing GuidesAccessibility Development Strategy API Routes Backend For Frontend Breadcrumbs Guide Browser Support Client Data Module Constraints Contributing CSS Files Data Loading Data Writes Dependency optimization Deployment Disabling JavaScript Environment Variables Error Handling FAQs File Uploads Form Validation Gotchas Index Query Param Lazy Route Discovery Local TLS Manual Dev Server MDX Migrating from React Router Not Found Handling Performance Presets Resource Routes Server Bundles Single Fetch SPA Mode Streaming Templates TypeScript Vite Getting StartedQuick Start (5m) Tutorial (30m) Upgrading to v2 Community Future Flags Changelog Discussion TopicsIntroduction, Technical Explanation Runtimes, Adapters, Templates, and Deployment Route Configuration Fullstack Data Flow Server vs. Client Code Execution React Router Progressive Enhancement Pending UI State Management Network Concurrency Management Form vs. fetcher Hot Module Replacement Form Resubmissions File Conventions.client modules .server modules Asset Imports entry.client entry.server root Route File Naming vite.config.ts Route Moduleaction clientAction clientLoader Component ErrorBoundary handle headers HydrateFallback links loader meta shouldRevalidate ComponentsAwait Form Link Links LiveReload Meta NavLink Outlet PrefetchPageLinks Scripts ScrollRestoration HooksuseActionData useAsyncError 🆕useAsyncValue 🆕useBeforeUnload useBlocker useFetcher useFetchers useFormAction useHref useLoaderData useLocation useMatches useNavigate useNavigation useNavigationType useOutlet useOutletContext useParams unstable_usePrompt useResolvedPath useRevalidator 🆕useRouteError 🆕useRouteLoaderData useSearchParams useSubmit useViewTransitionState UtilitiesCookies createRemixStub data defer isRouteErrorResponse json unstable_parseMultipartFormData redirect redirectDocument replace Sessions unstable_createFileUploadHandler unstable_createMemoryUploadHandler StylingCSS Bundling Regular CSS CSS Imports CSS in JS CSS Modules PostCSS Tailwind Vanilla Extract Other API@remix-run/dev CLI 🆕@remix-run/{adapter} @remix-run/serve create-remix (CLI) @remix-run/node @remix-run/testing GuidesAccessibility Development Strategy API Routes Backend For Frontend Breadcrumbs Guide Browser Support Client Data Module Constraints Contributing CSS Files Data Loading Data Writes Dependency optimization Deployment Disabling JavaScript Environment Variables Error Handling FAQs File Uploads Form Validation Gotchas Index Query Param Lazy Route Discovery Local TLS Manual Dev Server MDX Migrating from React Router Not Found Handling Performance Presets Resource Routes Server Bundles Single Fetch SPA Mode Streaming Templates TypeScript Vite On this pageUpdate to latest v2.xRemove installGlobalsAdopt the Vite Pluginv3_fetcherPersistv3_relativeSplatPathv3_throwAbortReasonv3_lazyRouteDiscoveryv3_singleFetchv3_routeConfigDeprecations@remix-run/eslint-configjsondeferSerializeFromMultipart Form Data and File Upload utilitiesOn this pageUpdate to latest v2.xRemove installGlobalsAdopt the Vite Pluginv3_fetcherPersistv3_relativeSplatPathv3_throwAbortReasonv3_lazyRouteDiscoveryv3_singleFetchv3_routeConfigDeprecations@remix-run/eslint-configjsondeferSerializeFromMultipart Form Data and File Upload utilitiesFuture Flags and Deprecations This guide walks you through the process of adopting future flags in your Remix app. By following this strategy, you will be able to upgrade to the next major version of Remix with minimal changes. To read more about future flags, see Development Strategy. We highly recommend you make a commit after each step and ship it instead of doing everything all at once. Most flags can be adopted in any order, with exceptions noted below. Update to latest v2.x First update to the latest minor version of v2.x to have the latest future flags. You will likely see a number of deprecation warnings as you upgrade, which we'll cover below. 👉 Update to latest v2 npm install @remix-run/{dev,react,node,etc.}@2 Remove installGlobals Background Previously Remix required a fetch polyfill to be installed. This was achieved by calling installGlobals(). The next major version requires a minimum of Node 20 to take advantage of the built-in fetch support. Note: if you are using Miniflare/Cloudflare worker with your remix project, ensure your compatibility flag is set to 2023-03-01 or later as well. 👉 Update to Node 20+ It is recommended that you upgrade to the latest even-numbered version of Node LTS. 👉 Remove installGlobals import { vitePlugin as remix } from \"@remix-run/dev\"; import { defineConfig } from \"vite\"; -installGlobals(); export default defineConfig({ plugins: [remix()], }); Adopt the Vite Plugin Background Remix no longer uses its own, closed compiler (now referred to as the \"Classic Compiler\") and instead uses Vite. Vite is a powerful, performant and extensible development environment for JavaScript projects. View the Vite docs for more information on performance, troubleshooting, etc. While this is not a future flag, new features and some feature flags are only available in the Vite plugin, and the Classic Compiler will be removed in the next version of Remix. 👉 Install Vite npm install -D vite Update your Code 👉 Replace remix.config.js with vite.config.ts at the root of your Remix app import { vitePlugin as remix } from \"@remix-run/dev\"; import { defineConfig } from \"vite\"; export default defineConfig({ plugins: [remix()], }); The subset of supported Remix config options should be passed directly to the plugin: export default defineConfig({ plugins: [ remix({ ignoredRouteFiles: [\"**/*.css\"], }), ], }); 👉 Add unstable_optimizeDeps (optional) Many users found that automatically optimizing dependencies helped them more easily adopt the Vite plugin. For this reason we added the unstable_optimizeDeps flag to the Vite plugin. This flag will remain in an \"unstable\" state until React Router v7, so it is not critical that you adopt this in your Remix v2 app before upgrading to React Router v7. export default defineConfig({ plugins: [ remix({ future: { unstable_optimizeDeps: true, }, }), ], }); 👉 Remove \u003cLiveReload/\u003e, keep \u003cScripts /\u003e import { - LiveReload, Outlet, Scripts, } export default function App() { return ( \u003chtml\u003e \u003chead\u003e \u003c/head\u003e \u003cbody\u003e \u003cOutlet /\u003e - \u003cLiveReload /\u003e \u003cScripts /\u003e \u003c/body\u003e \u003c/html\u003e ) } 👉 Update tsconfig.json Update the types field in tsconfig.json and make sure skipLibCheck, module, and moduleResolution are all set correctly. { \"compilerOptions\": { \"types\": [\"@remix-run/node\", \"vite/client\"], \"skipLibCheck\": true, \"module\": \"ESNext\", \"moduleResolution\": \"Bundler\" } } 👉 Update/remove remix.env.d.ts Remove the following type declarations in remix.env.d.ts - /// \u003creference types=\"@remix-run/dev\" /\u003e - /// \u003creference types=\"@remix-run/node\" /\u003e If remix.env.d.ts is now empty, delete it rm remix.env.d.ts Configure path aliases Vite does not provide any path aliases by default. If you were relying on this feature, such as defining ~ as an alias for the app directory, you can install the vite-tsconfig-paths plugin to automatically resolve path aliases from your tsconfig.json in Vite, matching the behavior of the Remix compiler: 👉 Install vite-tsconfig-paths npm install -D vite-tsconfig-paths 👉 Add vite-tsconfig-paths to your Vite config import { vitePlugin as remix } from \"@remix-run/dev\"; import { defineConfig } from \"vite\"; import tsconfigPaths from \"vite-tsconfig-paths\"; export default defineConfig({ plugins: [remix(), tsconfigPaths()], }); Remove @remix-run/css-bundle Vite has built-in support for CSS side effect imports, PostCSS and CSS Modules, among other CSS bundling features. The Remix Vite plugin automatically attaches bundled CSS to the relevant routes. The @remix-run/css-bundle package is redundant when using Vite since its cssBundleHref export will always be undefined. 👉 Uninstall @remix-run/css-bundle npm uninstall @remix-run/css-bundle 👉 Remove references to cssBundleHref - import { cssBundleHref } from \"@remix-run/css-bundle\"; import type { LinksFunction } from \"@remix-run/node\"; // or cloudflare/deno export const links: LinksFunction = () =\u003e [ - ...(cssBundleHref - ? [{ rel: \"stylesheet\", href: cssBundleHref }] - : []), // ... ]; Fix up CSS imports referenced in links If you are referencing CSS in a links function, you'll need to update the corresponding CSS imports to use Vite's explicit ?url import syntax. 👉 Add ?url to CSS imports used in links -import styles from \"~/styles/dashboard.css\"; +import styles from \"~/styles/dashboard.css?url\"; export const links = () =\u003e { return [ { rel: \"stylesheet\", href: styles } ]; } Migrate Tailwind CSS or Vanilla Extract If you are using Tailwind CSS or Vanilla Extract, see the full migration guide. Migrate from Remix App Server 👉 Update your dev, build and start scripts { \"scripts\": { \"dev\": \"remix vite:dev\", \"build\": \"remix vite:build\", \"start\": \"remix-serve ./build/server/index.js\" } } 👉 Configure your Vite dev server port (optional) export default defineConfig({ server: { port: 3000, }, plugins: [remix()], }); Migrate a custom server If you are migrating a customer server or Cloudflare Functions, see the full migration guide. Migrate MDX routes If you're using MDX, you should use the official MDX Rollup plugin. See the full migration guide for a step-by-step walkthrough. v3_fetcherPersist Background The fetcher lifecycle is now based on when it returns to an idle state rather than when its owner component unmounts: View the RFC for more information. 👉 Enable the Flag remix({ future: { v3_fetcherPersist: true, }, }); Update your Code It's unlikely to affect your app. You may want to check any usage of useFetchers as they may persist longer than they did before. Depending on what you're doing, you may render something longer than before. v3_relativeSplatPath Background Changes the relative path matching and linking for multi-segment splats paths like dashboard/* (vs. just *). View the CHANGELOG for more information. 👉 Enable the Flag remix({ future: { v3_relativeSplatPath: true, }, }); Update your Code If you have any routes with a path + a splat like dashboard.$.tsx or route(\"dashboard/*\") that have relative links like \u003cLink to=\"relative\"\u003e or \u003cLink to=\"../relative\"\u003e beneath it, you will need to update your code. 👉 Split the route into two For any splat routes split it into a layout route and a child route with the splat: └── routes ├── _index.tsx + ├── dashboard.tsx └── dashboard.$.tsx // or routes(defineRoutes) { return defineRoutes((route) =\u003e { route(\"/\", \"home/route.tsx\", { index: true }); - route(\"dashboard/*\", \"dashboard/route.tsx\") + route(\"dashboard\", \"dashboard/layout.tsx\", () =\u003e { + route(\"*\", \"dashboard/route.tsx\"); }); }); }, 👉 Update relative links Update any \u003cLink\u003e elements with relative links within that route tree to include the extra .. relative segment to continue linking to the same place: // dashboard.$.tsx or dashboard/route.tsx function Dashboard() { return ( \u003cdiv\u003e \u003ch2\u003eDashboard\u003c/h2\u003e \u003cnav\u003e - \u003cLink to=\"\"\u003eDashboard Home\u003c/Link\u003e - \u003cLink to=\"team\"\u003eTeam\u003c/Link\u003e - \u003cLink to=\"projects\"\u003eProjects\u003c/Link\u003e + \u003cLink to=\"../\"\u003eDashboard Home\u003c/Link\u003e + \u003cLink to=\"../team\"\u003eTeam\u003c/Link\u003e + \u003cLink to=\"../projects\"\u003eProjects\u003c/Link\u003e \u003c/nav\u003e \u003c/div\u003e ); } v3_throwAbortReason Background When a server-side request is aborted, such as when a user navigates away from a page before the loader finishes, Remix will throw the request.signal.reason instead of an error such as new Error(\"query() call aborted...\"). 👉 Enable the Flag remix({ future: { v3_throwAbortReason: true, }, }); Update your Code You likely won't need to adjust any code, unless you had custom logic inside of handleError that was matching the previous error message to differentiate it from other errors. v3_lazyRouteDiscovery Background With this flag, Remix no longer sends the full route manifest up to the client on initial load. Instead, Remix only sends the server-rendered routes up in the manifest and then fetches the remaining routes as the user navigates around the application. Additional details are available in the docs and the blog post 👉 Enable the Flag remix({ future: { v3_lazyRouteDiscovery: true, }, }); Update your Code You shouldn't need to make any changes to your application code for this feature to work. You may find some usage for the new \u003cLink discover\u003e API if you wish to disable eager route discovery on certain links. v3_singleFetch This flag requires the Vite plugin. Background With this flag, Remix uses a single fetch for data requests during client-side navigations. This simplifies data loading by treating data requests the same as document requests, eliminating the need to handle headers and caching differently. For advanced use cases, you can still opt into fine-grained revalidations. View the \"Single Fetch\" docs for more information. 👉 Enable the Flag (and the types) import { vitePlugin as remix } from \"@remix-run/dev\"; import { defineConfig } from \"vite\"; import tsconfigPaths from \"vite-tsconfig-paths\"; declare module \"@remix-run/node\" { // or cloudflare, deno, etc. interface Future { v3_singleFetch: true; } } export default defineConfig({ plugins: [ remix({ future: { v3_singleFetch: true, }, }), tsconfigPaths(), ], }); Update your Code You should be able to mostly use your code as-is with the flag enabled, but the following changes should be made over time and will be required prior to the next major version. 👉 Remove json()/defer() in favor of raw objects Single Fetch supports JSON objects and Promises out of the box, so you can return the raw data from your loader/action functions: -import { json } from \"@remix-run/node\"; export async function loader({}: LoaderFunctionArgs) { let tasks = await fetchTasks(); - return json(tasks); + return tasks; } -import { defer } from \"@remix-run/node\"; export async function loader({}: LoaderFunctionArgs) { let lazyStuff = fetchLazyStuff(); let tasks = await fetchTasks(); - return defer({ tasks, lazyStuff }); + return { tasks, lazyStuff }; } If you were using the second parameter of json/defer to set a custom status or headers on your response, you can continue doing so via the new data API (please note that you will need a headers export to apply those headers to Single Fetch data requests): -import { json } from \"@remix-run/node\"; +import { data } from \"@remix-run/node\"; // This example assumes you already have a headers function to handle header // merging for your document requests export function headers() { // ... } export async function loader({}: LoaderFunctionArgs) { let tasks = await fetchTasks(); - return json(tasks, { + return data(tasks, { headers: { \"Cache-Control\": \"public, max-age=604800\" } }); } 👉 Adjust your server abort delay If you were using a custom ABORT_DELAY in your entry.server.tsx file, you should change that to use the new streamTimeout API leveraged by Single Fetch: -const ABORT_DELAY = 5000; +// Reject/cancel all pending promises after 5 seconds +export const streamTimeout = 5000; // ... function handleBrowserRequest(/* ... */) { return new Promise((resolve, reject) =\u003e { const { pipe, abort } = renderToPipeableStream( \u003cRemixServer context={remixContext} url={request.url} - abortDelay={ABORT_DELAY} /\u003e, { onShellReady() { /* ... */ }, onShellError(error: unknown) { /* ... */ }, onError(error: unknown) { /* ... */ }, } ); - setTimeout(abort, ABORT_DELAY); + // Automatically timeout the React renderer after 6 seconds, which ensures + // React has enough time to flush down the rejected boundary contents + setTimeout(abort, streamTimeout + 1000); }); } v3_routeConfig This flag requires the Vite plugin. Config-based routing is the new default in React Router v7, configured via the routes.ts file in the app directory. Support for routes.ts and its related APIs in Remix are designed as a migration path to help minimize the number of changes required when moving your Remix project over to React Router v7. While some new packages have been introduced within the @remix-run scope, these new packages only exist to keep the code in routes.ts as similar as possible to the equivalent code for React Router v7. When the v3_routeConfig future flag is enabled, Remix's built-in file system routing will be disabled and your project will opt into React Router v7's config-based routing. If you prefer to keep using Remix's file-based routing, we cover how to enable it in routes.ts below. Update your code To migrate Remix's file system routing and route config to the equivalent setup in React Router v7, you can follow these steps: 👉 Enable the Flag remix({ future: { v3_routeConfig: true, }, }); 👉 Install @remix-run/route-config This package matches the API of React Router v7's @react-router/dev/routes, making the React Router v7 migration as easy as possible. npm install -D @remix-run/route-config This provides the core RouteConfig type as well as a set of helpers for configuring routes in code. 👉 Add an app/routes.ts file without any configured routes touch app/routes.ts import type { RouteConfig } from \"@remix-run/route-config\"; export default [] satisfies RouteConfig; This is a good way to check that your new routes.ts file is being picked up successfully. Your app should now be rendering a blank page since there aren't any routes defined yet. 👉 Install @remix-run/fs-routes and use it in routes.ts npm install -D @remix-run/fs-routes This package matches the API of React Router v7's @react-router/fs-routes, making the React Router v7 migration as easy as possible. If you've configured ignoredRouteFiles to [\"**/*\"], you should skip this step since you're already opting out of Remix's file system routing. import { flatRoutes } from \"@remix-run/fs-routes\"; export default flatRoutes(); 👉 If you used the routes config option, add @remix-run/routes-option-adapter and use it in routes.ts Remix provides a mechanism for defining routes in code and plugging in alternative file system routing conventions, available via the routes option on the Vite plugin. To make migration easier, an adapter package is available that converts Remix's routes option into React Router's RouteConfig array. To get started, first install the adapter: npm install -D @remix-run/routes-option-adapter This package matches the API of React Router v7's @react-router/remix-routes-option-adapter, making the React Router v7 migration as easy as possible. Then, update your routes.ts file to use the adapter, passing the value of your routes option to the remixRoutesOptionAdapter function which will return an array of configured routes. For example, if you were using the routes option to use an alternative file system routing implementation like remix-flat-routes: import { type RouteConfig } from \"@remix-run/route-config\"; import { remixRoutesOptionAdapter } from \"@remix-run/routes-option-adapter\"; import { flatRoutes } from \"remix-flat-routes\"; export default remixRoutesOptionAdapter((defineRoutes) =\u003e flatRoutes(\"routes\", defineRoutes) ) satisfies RouteConfig; Or, if you were using the routes option to define config-based routes: import { flatRoutes } from \"@remix-run/fs-routes\"; import { type RouteConfig } from \"@remix-run/route-config\"; import { remixRoutesOptionAdapter } from \"@remix-run/routes-option-adapter\"; export default remixRoutesOptionAdapter((defineRoutes) =\u003e { return defineRoutes((route) =\u003e { route(\"/\", \"home/route.tsx\", { index: true }); route(\"about\", \"about/route.tsx\"); route(\"\", \"concerts/layout.tsx\", () =\u003e { route(\"trending\", \"concerts/trending.tsx\"); route(\":city\", \"concerts/city.tsx\"); }); }); }) satisfies RouteConfig; If you're defining config-based routes in this way, you might want to consider migrating to the new route config API since it's more streamlined while still being very similar to the old API. For example, the routes above would look like this: import { type RouteConfig, route, layout, index, } from \"@remix-run/route-config\"; export default [ index(\"home/route.tsx\"), route(\"about\", \"about/route.tsx\"), layout(\"concerts/layout.tsx\", [ route(\"trending\", \"concerts/trending.tsx\"), route(\":city\", \"concerts/city.tsx\"), ]), ] satisfies RouteConfig; Note that if you need to mix and match different route config approaches, they can be merged into a single array of routes. The RouteConfig type ensures that everything is still valid. import { flatRoutes } from \"@remix-run/fs-routes\"; import type { RouteConfig } from \"@remix-run/route-config\"; import { route } from \"@remix-run/route-config\"; import { remixRoutesOptionAdapter } from \"@remix-run/routes-option-adapter\"; export default [ ...(await flatRoutes({ rootDirectory: \"fs-routes\" })), ...(await remixRoutesOptionAdapter(/* ... */)), route(\"/hello\", \"routes/hello.tsx\"), ] satisfies RouteConfig; Deprecations @remix-run/eslint-config The @remix-run/eslint-config package is deprecated and will not be included in React Router v7. We recommend moving towards a streamlined ESLint config such as the ones included in the Remix templates. json This utility is deprecated and will be removed in React Router v7 in favor of Single Fetch naked object returns. If you were not relying on json to serialize your data (such as stringifying Date objects), you can safely remove it. If you were returning headers or status via json, you can use the new data util as a drop-in replacement to set those values. If you want to serialize your data to JSON, you can use the native Response.json() method. View the Single Fetch docs for more information. defer This utility is deprecated and will be removed in React Router v7 in favor of Single Fetch naked object returns. If you were returning headers or status via defer, you can use the new data util as a drop-in replacement to set those values. View the Single Fetch docs for more information. SerializeFrom This type is deprecated and will be removed in React Router v7 since Single Fetch no longer serializes data to JSON. If you are relying on SerializeFrom to unwrap your loader/action data, you can use a custom type like this: type SerializeFrom\u003cT\u003e = ReturnType\u003ctypeof useLoaderData\u003cT\u003e\u003e; In most cases, you should be able to just remove SerializeFrom and use the types returned from useLoaderData/useActionData, or the types of the data in loader/action functions. Multipart Form Data and File Upload utilities The following utilities are deprecated and will be removed in React Router v7: unstable_parseMultipartFormData unstable_composeUploadHandlers unstable_createFileUploadHandler unstable_createMemoryUploadHandler We recommend using @mjackson/form-data-parser and @mjackson/file-storage to handle multipart form data and file uploads. You can also check out the React Router \"File Uploads\" doc or \"File uploads with Remix\" blog post for guides on using these libraries.© Shopify, Inc.•Docs and examples licensed under MITEdit((storageKey2, restoreKey) =\u003e { if (!window.history.state || !window.history.state.key) { let key = Math.random().toString(32).slice(2); window.history.replaceState({ key }, \"\"); } try { let positions = JSON.parse(sessionStorage.getItem(storageKey2) || \"{}\"); let storedY = positions[restoreKey || window.history.state.key]; if (typeof storedY === \"number\") { window.scrollTo(0, storedY); } } catch (error) { console.error(error); sessionStorage.removeItem(storageKey2); } })(\"react-router-scroll-positions\", null)window.__reactRouterContext = {\"basename\":\"/\",\"future\":{\"unstable_optimizeDeps\":true,\"unstable_subResourceIntegrity\":false,\"v8_middleware\":true,\"v8_splitRouteModules\":true,\"v8_viteEnvironmentApi\":true},\"routeDiscovery\":{\"mode\":\"initial\"},\"ssr\":true,\"isSpaMode\":false};window.__reactRouterContext.stream = new ReadableStream({start(controller){window.__reactRouterContext.streamController = controller;}}).pipeThrough(new TextEncoderStream());import \"/assets/manifest-b010e014.js\"; import * as route0 from \"/assets/root-CtUYAfRS.js\"; import * as route1 from \"/assets/docs-DauuYQK6.js\"; import * as route2 from \"/assets/docs._-B4dRXAHv.js\"; window.__reactRouterRouteModules = {\"root\":route0,\"routes/docs\":route1,\"routes/docs.$\":route2}; import(\"/assets/entry.client-q2ogymM2.js\");window.__reactRouterContext.streamController.enqueue(\"[{\\\"_1\\\":2,\\\"_1005\\\":-5,\\\"_1006\\\":-5},\\\"loaderData\\\",{\\\"_3\\\":4,\\\"_11\\\":12,\\\"_949\\\":950},\\\"root\\\",{\\\"_5\\\":6,\\\"_7\\\":8,\\\"_9\\\":10},\\\"host\\\",\\\"localhost\\\",\\\"siteUrl\\\",\\\"https://v2.remix.run\\\",\\\"noIndex\\\",false,\\\"routes/docs\\\",{\\\"_13\\\":14},\\\"menu\\\",[15,72,160,214,292,364,527,611,665,707],{\\\"_16\\\":17,\\\"_22\\\":23,\\\"_24\\\":25,\\\"_26\\\":10,\\\"_27\\\":28},\\\"attrs\\\",{\\\"_18\\\":19,\\\"_20\\\":21},\\\"title\\\",\\\"Getting Started\\\",\\\"order\\\",1,\\\"filename\\\",\\\"start/index.md\\\",\\\"slug\\\",\\\"start\\\",\\\"hasContent\\\",\\\"children\\\",[29,36,43,50,59,66],{\\\"_16\\\":30,\\\"_22\\\":32,\\\"_24\\\":33,\\\"_26\\\":34,\\\"_27\\\":35},{\\\"_18\\\":31,\\\"_20\\\":21},\\\"Quick Start (5m)\\\",\\\"start/quickstart.md\\\",\\\"start/quickstart\\\",true,[],{\\\"_16\\\":37,\\\"_22\\\":40,\\\"_24\\\":41,\\\"_26\\\":34,\\\"_27\\\":42},{\\\"_18\\\":38,\\\"_20\\\":39},\\\"Tutorial (30m)\\\",2,\\\"start/tutorial.md\\\",\\\"start/tutorial\\\",[],{\\\"_16\\\":44,\\\"_22\\\":47,\\\"_24\\\":48,\\\"_26\\\":34,\\\"_27\\\":49},{\\\"_18\\\":45,\\\"_20\\\":46},\\\"Upgrading to v2\\\",3,\\\"start/v2.md\\\",\\\"start/v2\\\",[],{\\\"_16\\\":51,\\\"_22\\\":56,\\\"_24\\\":57,\\\"_26\\\":34,\\\"_27\\\":58},{\\\"_18\\\":52,\\\"_53\\\":54,\\\"_20\\\":55},\\\"Community\\\",\\\"description\\\",\\\"Community resources for learning Remix and related technologies\\\",4,\\\"start/community.md\\\",\\\"start/community\\\",[],{\\\"_16\\\":60,\\\"_22\\\":63,\\\"_24\\\":64,\\\"_26\\\":34,\\\"_27\\\":65},{\\\"_18\\\":61,\\\"_20\\\":62},\\\"Future Flags\\\",5,\\\"start/future-flags.md\\\",\\\"start/future-flags\\\",[],{\\\"_16\\\":67,\\\"_22\\\":69,\\\"_24\\\":70,\\\"_26\\\":34,\\\"_27\\\":71},{\\\"_18\\\":68},\\\"Changelog\\\",\\\"start/changelog.md\\\",\\\"start/changelog\\\",[],{\\\"_16\\\":73,\\\"_22\\\":75,\\\"_24\\\":76,\\\"_26\\\":10,\\\"_27\\\":77},{\\\"_18\\\":74,\\\"_20\\\":39},\\\"Discussion Topics\\\",\\\"discussion/index.md\\\",\\\"discussion\\\",[78,84,90,96,102,108,115,122,129,136,142,148,154],{\\\"_16\\\":79,\\\"_22\\\":81,\\\"_24\\\":82,\\\"_26\\\":34,\\\"_27\\\":83},{\\\"_18\\\":80,\\\"_20\\\":21},\\\"Introduction, Technical Explanation\\\",\\\"discussion/introduction.md\\\",\\\"discussion/introduction\\\",[],{\\\"_16\\\":85,\\\"_22\\\":87,\\\"_24\\\":88,\\\"_26\\\":34,\\\"_27\\\":89},{\\\"_18\\\":86,\\\"_20\\\":39},\\\"Runtimes, Adapters, Templates, and Deployment\\\",\\\"discussion/runtimes.md\\\",\\\"discussion/runtimes\\\",[],{\\\"_16\\\":91,\\\"_22\\\":93,\\\"_24\\\":94,\\\"_26\\\":34,\\\"_27\\\":95},{\\\"_18\\\":92,\\\"_20\\\":46},\\\"Route Configuration\\\",\\\"discussion/routes.md\\\",\\\"discussion/routes\\\",[],{\\\"_16\\\":97,\\\"_22\\\":99,\\\"_24\\\":100,\\\"_26\\\":34,\\\"_27\\\":101},{\\\"_18\\\":98,\\\"_20\\\":55},\\\"Fullstack Data Flow\\\",\\\"discussion/data-flow.md\\\",\\\"discussion/data-flow\\\",[],{\\\"_16\\\":103,\\\"_22\\\":105,\\\"_24\\\":106,\\\"_26\\\":34,\\\"_27\\\":107},{\\\"_18\\\":104,\\\"_20\\\":62},\\\"Server vs. Client Code Execution\\\",\\\"discussion/server-vs-client.md\\\",\\\"discussion/server-vs-client\\\",[],{\\\"_16\\\":109,\\\"_22\\\":112,\\\"_24\\\":113,\\\"_26\\\":34,\\\"_27\\\":114},{\\\"_18\\\":110,\\\"_20\\\":111},\\\"React Router\\\",6,\\\"discussion/react-router.md\\\",\\\"discussion/react-router\\\",[],{\\\"_16\\\":116,\\\"_22\\\":119,\\\"_24\\\":120,\\\"_26\\\":34,\\\"_27\\\":121},{\\\"_18\\\":117,\\\"_20\\\":118},\\\"Progressive Enhancement\\\",7,\\\"discussion/progressive-enhancement.md\\\",\\\"discussion/progressive-enhancement\\\",[],{\\\"_16\\\":123,\\\"_22\\\":126,\\\"_24\\\":127,\\\"_26\\\":34,\\\"_27\\\":128},{\\\"_18\\\":124,\\\"_20\\\":125},\\\"Pending UI\\\",8,\\\"discussion/pending-ui.md\\\",\\\"discussion/pending-ui\\\",[],{\\\"_16\\\":130,\\\"_22\\\":133,\\\"_24\\\":134,\\\"_26\\\":34,\\\"_27\\\":135},{\\\"_18\\\":131,\\\"_20\\\":132},\\\"State Management\\\",9,\\\"discussion/state-management.md\\\",\\\"discussion/state-management\\\",[],{\\\"_16\\\":137,\\\"_22\\\":139,\\\"_24\\\":140,\\\"_26\\\":34,\\\"_27\\\":141},{\\\"_18\\\":138},\\\"Network Concurrency Management\\\",\\\"discussion/concurrency.md\\\",\\\"discussion/concurrency\\\",[],{\\\"_16\\\":143,\\\"_22\\\":145,\\\"_24\\\":146,\\\"_26\\\":34,\\\"_27\\\":147},{\\\"_18\\\":144},\\\"Form vs. fetcher\\\",\\\"discussion/form-vs-fetcher.md\\\",\\\"discussion/form-vs-fetcher\\\",[],{\\\"_16\\\":149,\\\"_22\\\":151,\\\"_24\\\":152,\\\"_26\\\":34,\\\"_27\\\":153},{\\\"_18\\\":150},\\\"Hot Module Replacement\\\",\\\"discussion/hot-module-replacement.md\\\",\\\"discussion/hot-module-replacement\\\",[],{\\\"_16\\\":155,\\\"_22\\\":157,\\\"_24\\\":158,\\\"_26\\\":34,\\\"_27\\\":159},{\\\"_18\\\":156},\\\"Form Resubmissions\\\",\\\"discussion/resubmissions.md\\\",\\\"discussion/resubmissions\\\",[],{\\\"_16\\\":161,\\\"_22\\\":163,\\\"_24\\\":164,\\\"_26\\\":10,\\\"_27\\\":165},{\\\"_18\\\":162,\\\"_20\\\":46},\\\"File Conventions\\\",\\\"file-conventions/index.md\\\",\\\"file-conventions\\\",[166,173,179,185,191,197,202,208],{\\\"_16\\\":167,\\\"_22\\\":170,\\\"_24\\\":171,\\\"_26\\\":34,\\\"_27\\\":172},{\\\"_18\\\":168,\\\"_169\\\":10},\\\".client modules\\\",\\\"toc\\\",\\\"file-conventions/-client.md\\\",\\\"file-conventions/-client\\\",[],{\\\"_16\\\":174,\\\"_22\\\":176,\\\"_24\\\":177,\\\"_26\\\":34,\\\"_27\\\":178},{\\\"_18\\\":175,\\\"_169\\\":10},\\\".server modules\\\",\\\"file-conventions/-server.md\\\",\\\"file-conventions/-server\\\",[],{\\\"_16\\\":180,\\\"_22\\\":182,\\\"_24\\\":183,\\\"_26\\\":34,\\\"_27\\\":184},{\\\"_18\\\":181,\\\"_169\\\":10},\\\"Asset Imports\\\",\\\"file-conventions/asset-imports.md\\\",\\\"file-conventions/asset-imports\\\",[],{\\\"_16\\\":186,\\\"_22\\\":188,\\\"_24\\\":189,\\\"_26\\\":34,\\\"_27\\\":190},{\\\"_18\\\":187,\\\"_169\\\":10},\\\"entry.client\\\",\\\"file-conventions/entry.client.md\\\",\\\"file-conventions/entry.client\\\",[],{\\\"_16\\\":192,\\\"_22\\\":194,\\\"_24\\\":195,\\\"_26\\\":34,\\\"_27\\\":196},{\\\"_18\\\":193,\\\"_169\\\":10},\\\"entry.server\\\",\\\"file-conventions/entry.server.md\\\",\\\"file-conventions/entry.server\\\",[],{\\\"_16\\\":198,\\\"_22\\\":199,\\\"_24\\\":200,\\\"_26\\\":34,\\\"_27\\\":201},{\\\"_18\\\":3,\\\"_169\\\":10},\\\"file-conventions/root.md\\\",\\\"file-conventions/root\\\",[],{\\\"_16\\\":203,\\\"_22\\\":205,\\\"_24\\\":206,\\\"_26\\\":34,\\\"_27\\\":207},{\\\"_18\\\":204},\\\"Route File Naming\\\",\\\"file-conventions/routes.md\\\",\\\"file-conventions/routes\\\",[],{\\\"_16\\\":209,\\\"_22\\\":211,\\\"_24\\\":212,\\\"_26\\\":34,\\\"_27\\\":213},{\\\"_18\\\":210},\\\"vite.config.ts\\\",\\\"file-conventions/vite-config.md\\\",\\\"file-conventions/vite-config\\\",[],{\\\"_16\\\":215,\\\"_22\\\":217,\\\"_24\\\":218,\\\"_26\\\":10,\\\"_27\\\":219},{\\\"_18\\\":216,\\\"_20\\\":55},\\\"Route Module\\\",\\\"route/index.md\\\",\\\"route\\\",[220,226,232,238,244,250,256,262,268,274,280,286],{\\\"_16\\\":221,\\\"_22\\\":223,\\\"_24\\\":224,\\\"_26\\\":34,\\\"_27\\\":225},{\\\"_18\\\":222},\\\"action\\\",\\\"route/action.md\\\",\\\"route/action\\\",[],{\\\"_16\\\":227,\\\"_22\\\":229,\\\"_24\\\":230,\\\"_26\\\":34,\\\"_27\\\":231},{\\\"_18\\\":228},\\\"clientAction\\\",\\\"route/client-action.md\\\",\\\"route/client-action\\\",[],{\\\"_16\\\":233,\\\"_22\\\":235,\\\"_24\\\":236,\\\"_26\\\":34,\\\"_27\\\":237},{\\\"_18\\\":234},\\\"clientLoader\\\",\\\"route/client-loader.md\\\",\\\"route/client-loader\\\",[],{\\\"_16\\\":239,\\\"_22\\\":241,\\\"_24\\\":242,\\\"_26\\\":34,\\\"_27\\\":243},{\\\"_18\\\":240},\\\"Component\\\",\\\"route/component.md\\\",\\\"route/component\\\",[],{\\\"_16\\\":245,\\\"_22\\\":247,\\\"_24\\\":248,\\\"_26\\\":34,\\\"_27\\\":249},{\\\"_18\\\":246},\\\"ErrorBoundary\\\",\\\"route/error-boundary.md\\\",\\\"route/error-boundary\\\",[],{\\\"_16\\\":251,\\\"_22\\\":253,\\\"_24\\\":254,\\\"_26\\\":34,\\\"_27\\\":255},{\\\"_18\\\":252},\\\"handle\\\",\\\"route/handle.md\\\",\\\"route/handle\\\",[],{\\\"_16\\\":257,\\\"_22\\\":259,\\\"_24\\\":260,\\\"_26\\\":34,\\\"_27\\\":261},{\\\"_18\\\":258},\\\"headers\\\",\\\"route/headers.md\\\",\\\"route/headers\\\",[],{\\\"_16\\\":263,\\\"_22\\\":265,\\\"_24\\\":266,\\\"_26\\\":34,\\\"_27\\\":267},{\\\"_18\\\":264},\\\"HydrateFallback\\\",\\\"route/hydrate-fallback.md\\\",\\\"route/hydrate-fallback\\\",[],{\\\"_16\\\":269,\\\"_22\\\":271,\\\"_24\\\":272,\\\"_26\\\":34,\\\"_27\\\":273},{\\\"_18\\\":270},\\\"links\\\",\\\"route/links.md\\\",\\\"route/links\\\",[],{\\\"_16\\\":275,\\\"_22\\\":277,\\\"_24\\\":278,\\\"_26\\\":34,\\\"_27\\\":279},{\\\"_18\\\":276},\\\"loader\\\",\\\"route/loader.md\\\",\\\"route/loader\\\",[],{\\\"_16\\\":281,\\\"_22\\\":283,\\\"_24\\\":284,\\\"_26\\\":34,\\\"_27\\\":285},{\\\"_18\\\":282},\\\"meta\\\",\\\"route/meta.md\\\",\\\"route/meta\\\",[],{\\\"_16\\\":287,\\\"_22\\\":289,\\\"_24\\\":290,\\\"_26\\\":34,\\\"_27\\\":291},{\\\"_18\\\":288},\\\"shouldRevalidate\\\",\\\"route/should-revalidate.md\\\",\\\"route/should-revalidate\\\",[],{\\\"_16\\\":293,\\\"_22\\\":295,\\\"_24\\\":296,\\\"_26\\\":10,\\\"_27\\\":297},{\\\"_18\\\":294,\\\"_20\\\":62},\\\"Components\\\",\\\"components/index.md\\\",\\\"components\\\",[298,304,310,316,322,328,334,340,346,352,358],{\\\"_16\\\":299,\\\"_22\\\":301,\\\"_24\\\":302,\\\"_26\\\":34,\\\"_27\\\":303},{\\\"_18\\\":300},\\\"Await\\\",\\\"components/await.md\\\",\\\"components/await\\\",[],{\\\"_16\\\":305,\\\"_22\\\":307,\\\"_24\\\":308,\\\"_26\\\":34,\\\"_27\\\":309},{\\\"_18\\\":306},\\\"Form\\\",\\\"components/form.md\\\",\\\"components/form\\\",[],{\\\"_16\\\":311,\\\"_22\\\":313,\\\"_24\\\":314,\\\"_26\\\":34,\\\"_27\\\":315},{\\\"_18\\\":312},\\\"Link\\\",\\\"components/link.md\\\",\\\"components/link\\\",[],{\\\"_16\\\":317,\\\"_22\\\":319,\\\"_24\\\":320,\\\"_26\\\":34,\\\"_27\\\":321},{\\\"_18\\\":318,\\\"_169\\\":10},\\\"Links\\\",\\\"components/links.md\\\",\\\"components/links\\\",[],{\\\"_16\\\":323,\\\"_22\\\":325,\\\"_24\\\":326,\\\"_26\\\":34,\\\"_27\\\":327},{\\\"_18\\\":324,\\\"_169\\\":10},\\\"LiveReload\\\",\\\"components/live-reload.md\\\",\\\"components/live-reload\\\",[],{\\\"_16\\\":329,\\\"_22\\\":331,\\\"_24\\\":332,\\\"_26\\\":34,\\\"_27\\\":333},{\\\"_18\\\":330,\\\"_169\\\":10},\\\"Meta\\\",\\\"components/meta.md\\\",\\\"components/meta\\\",[],{\\\"_16\\\":335,\\\"_22\\\":337,\\\"_24\\\":338,\\\"_26\\\":34,\\\"_27\\\":339},{\\\"_18\\\":336},\\\"NavLink\\\",\\\"components/nav-link.md\\\",\\\"components/nav-link\\\",[],{\\\"_16\\\":341,\\\"_22\\\":343,\\\"_24\\\":344,\\\"_26\\\":34,\\\"_27\\\":345},{\\\"_18\\\":342},\\\"Outlet\\\",\\\"components/outlet.md\\\",\\\"components/outlet\\\",[],{\\\"_16\\\":347,\\\"_22\\\":349,\\\"_24\\\":350,\\\"_26\\\":34,\\\"_27\\\":351},{\\\"_18\\\":348,\\\"_169\\\":10},\\\"PrefetchPageLinks\\\",\\\"components/prefetch-page-links.md\\\",\\\"components/prefetch-page-links\\\",[],{\\\"_16\\\":353,\\\"_22\\\":355,\\\"_24\\\":356,\\\"_26\\\":34,\\\"_27\\\":357},{\\\"_18\\\":354,\\\"_169\\\":10},\\\"Scripts\\\",\\\"components/scripts.md\\\",\\\"components/scripts\\\",[],{\\\"_16\\\":359,\\\"_22\\\":361,\\\"_24\\\":362,\\\"_26\\\":34,\\\"_27\\\":363},{\\\"_18\\\":360},\\\"ScrollRestoration\\\",\\\"components/scroll-restoration.md\\\",\\\"components/scroll-restoration\\\",[],{\\\"_16\\\":365,\\\"_22\\\":367,\\\"_24\\\":368,\\\"_26\\\":10,\\\"_27\\\":369},{\\\"_18\\\":366,\\\"_20\\\":111},\\\"Hooks\\\",\\\"hooks/index.md\\\",\\\"hooks\\\",[370,376,383,389,395,401,407,413,419,425,431,437,443,449,455,461,467,473,479,485,491,497,503,509,515,521],{\\\"_16\\\":371,\\\"_22\\\":373,\\\"_24\\\":374,\\\"_26\\\":34,\\\"_27\\\":375},{\\\"_18\\\":372,\\\"_169\\\":10},\\\"useActionData\\\",\\\"hooks/use-action-data.md\\\",\\\"hooks/use-action-data\\\",[],{\\\"_16\\\":377,\\\"_22\\\":380,\\\"_24\\\":381,\\\"_26\\\":34,\\\"_27\\\":382},{\\\"_18\\\":378,\\\"_379\\\":34},\\\"useAsyncError\\\",\\\"new\\\",\\\"hooks/use-async-error.md\\\",\\\"hooks/use-async-error\\\",[],{\\\"_16\\\":384,\\\"_22\\\":386,\\\"_24\\\":387,\\\"_26\\\":34,\\\"_27\\\":388},{\\\"_18\\\":385,\\\"_379\\\":34},\\\"useAsyncValue\\\",\\\"hooks/use-async-value.md\\\",\\\"hooks/use-async-value\\\",[],{\\\"_16\\\":390,\\\"_22\\\":392,\\\"_24\\\":393,\\\"_26\\\":34,\\\"_27\\\":394},{\\\"_18\\\":391,\\\"_169\\\":10},\\\"useBeforeUnload\\\",\\\"hooks/use-before-unload.md\\\",\\\"hooks/use-before-unload\\\",[],{\\\"_16\\\":396,\\\"_22\\\":398,\\\"_24\\\":399,\\\"_26\\\":34,\\\"_27\\\":400},{\\\"_18\\\":397},\\\"useBlocker\\\",\\\"hooks/use-blocker.md\\\",\\\"hooks/use-blocker\\\",[],{\\\"_16\\\":402,\\\"_22\\\":404,\\\"_24\\\":405,\\\"_26\\\":34,\\\"_27\\\":406},{\\\"_18\\\":403},\\\"useFetcher\\\",\\\"hooks/use-fetcher.md\\\",\\\"hooks/use-fetcher\\\",[],{\\\"_16\\\":408,\\\"_22\\\":410,\\\"_24\\\":411,\\\"_26\\\":34,\\\"_27\\\":412},{\\\"_18\\\":409,\\\"_169\\\":10},\\\"useFetchers\\\",\\\"hooks/use-fetchers.md\\\",\\\"hooks/use-fetchers\\\",[],{\\\"_16\\\":414,\\\"_22\\\":416,\\\"_24\\\":417,\\\"_26\\\":34,\\\"_27\\\":418},{\\\"_18\\\":415},\\\"useFormAction\\\",\\\"hooks/use-form-action.md\\\",\\\"hooks/use-form-action\\\",[],{\\\"_16\\\":420,\\\"_22\\\":422,\\\"_24\\\":423,\\\"_26\\\":34,\\\"_27\\\":424},{\\\"_18\\\":421},\\\"useHref\\\",\\\"hooks/use-href.md\\\",\\\"hooks/use-href\\\",[],{\\\"_16\\\":426,\\\"_22\\\":428,\\\"_24\\\":429,\\\"_26\\\":34,\\\"_27\\\":430},{\\\"_18\\\":427},\\\"useLoaderData\\\",\\\"hooks/use-loader-data.md\\\",\\\"hooks/use-loader-data\\\",[],{\\\"_16\\\":432,\\\"_22\\\":434,\\\"_24\\\":435,\\\"_26\\\":34,\\\"_27\\\":436},{\\\"_18\\\":433},\\\"useLocation\\\",\\\"hooks/use-location.md\\\",\\\"hooks/use-location\\\",[],{\\\"_16\\\":438,\\\"_22\\\":440,\\\"_24\\\":441,\\\"_26\\\":34,\\\"_27\\\":442},{\\\"_18\\\":439,\\\"_169\\\":10},\\\"useMatches\\\",\\\"hooks/use-matches.md\\\",\\\"hooks/use-matches\\\",[],{\\\"_16\\\":444,\\\"_22\\\":446,\\\"_24\\\":447,\\\"_26\\\":34,\\\"_27\\\":448},{\\\"_18\\\":445},\\\"useNavigate\\\",\\\"hooks/use-navigate.md\\\",\\\"hooks/use-navigate\\\",[],{\\\"_16\\\":450,\\\"_22\\\":452,\\\"_24\\\":453,\\\"_26\\\":34,\\\"_27\\\":454},{\\\"_18\\\":451},\\\"useNavigation\\\",\\\"hooks/use-navigation.md\\\",\\\"hooks/use-navigation\\\",[],{\\\"_16\\\":456,\\\"_22\\\":458,\\\"_24\\\":459,\\\"_26\\\":34,\\\"_27\\\":460},{\\\"_18\\\":457},\\\"useNavigationType\\\",\\\"hooks/use-navigation-type.md\\\",\\\"hooks/use-navigation-type\\\",[],{\\\"_16\\\":462,\\\"_22\\\":464,\\\"_24\\\":465,\\\"_26\\\":34,\\\"_27\\\":466},{\\\"_18\\\":463},\\\"useOutlet\\\",\\\"hooks/use-outlet.md\\\",\\\"hooks/use-outlet\\\",[],{\\\"_16\\\":468,\\\"_22\\\":470,\\\"_24\\\":471,\\\"_26\\\":34,\\\"_27\\\":472},{\\\"_18\\\":469},\\\"useOutletContext\\\",\\\"hooks/use-outlet-context.md\\\",\\\"hooks/use-outlet-context\\\",[],{\\\"_16\\\":474,\\\"_22\\\":476,\\\"_24\\\":477,\\\"_26\\\":34,\\\"_27\\\":478},{\\\"_18\\\":475},\\\"useParams\\\",\\\"hooks/use-params.md\\\",\\\"hooks/use-params\\\",[],{\\\"_16\\\":480,\\\"_22\\\":482,\\\"_24\\\":483,\\\"_26\\\":34,\\\"_27\\\":484},{\\\"_18\\\":481},\\\"unstable_usePrompt\\\",\\\"hooks/use-prompt.md\\\",\\\"hooks/use-prompt\\\",[],{\\\"_16\\\":486,\\\"_22\\\":488,\\\"_24\\\":489,\\\"_26\\\":34,\\\"_27\\\":490},{\\\"_18\\\":487},\\\"useResolvedPath\\\",\\\"hooks/use-resolved-path.md\\\",\\\"hooks/use-resolved-path\\\",[],{\\\"_16\\\":492,\\\"_22\\\":494,\\\"_24\\\":495,\\\"_26\\\":34,\\\"_27\\\":496},{\\\"_18\\\":493,\\\"_379\\\":34},\\\"useRevalidator\\\",\\\"hooks/use-revalidator.md\\\",\\\"hooks/use-revalidator\\\",[],{\\\"_16\\\":498,\\\"_22\\\":500,\\\"_24\\\":501,\\\"_26\\\":34,\\\"_27\\\":502},{\\\"_18\\\":499,\\\"_379\\\":34},\\\"useRouteError\\\",\\\"hooks/use-route-error.md\\\",\\\"hooks/use-route-error\\\",[],{\\\"_16\\\":504,\\\"_22\\\":506,\\\"_24\\\":507,\\\"_26\\\":34,\\\"_27\\\":508},{\\\"_18\\\":505,\\\"_169\\\":10},\\\"useRouteLoaderData\\\",\\\"hooks/use-route-loader-data.md\\\",\\\"hooks/use-route-loader-data\\\",[],{\\\"_16\\\":510,\\\"_22\\\":512,\\\"_24\\\":513,\\\"_26\\\":34,\\\"_27\\\":514},{\\\"_18\\\":511},\\\"useSearchParams\\\",\\\"hooks/use-search-params.md\\\",\\\"hooks/use-search-params\\\",[],{\\\"_16\\\":516,\\\"_22\\\":518,\\\"_24\\\":519,\\\"_26\\\":34,\\\"_27\\\":520},{\\\"_18\\\":517},\\\"useSubmit\\\",\\\"hooks/use-submit.md\\\",\\\"hooks/use-submit\\\",[],{\\\"_16\\\":522,\\\"_22\\\":524,\\\"_24\\\":525,\\\"_26\\\":34,\\\"_27\\\":526},{\\\"_18\\\":523,\\\"_169\\\":10},\\\"useViewTransitionState\\\",\\\"hooks/use-view-transition-state.md\\\",\\\"hooks/use-view-transition-state\\\",[],{\\\"_16\\\":528,\\\"_22\\\":530,\\\"_24\\\":531,\\\"_26\\\":10,\\\"_27\\\":532},{\\\"_18\\\":529,\\\"_20\\\":111},\\\"Utilities\\\",\\\"utils/index.md\\\",\\\"utils\\\",[533,539,545,551,557,563,569,575,581,587,593,599,605],{\\\"_16\\\":534,\\\"_22\\\":536,\\\"_24\\\":537,\\\"_26\\\":34,\\\"_27\\\":538},{\\\"_18\\\":535},\\\"Cookies\\\",\\\"utils/cookies.md\\\",\\\"utils/cookies\\\",[],{\\\"_16\\\":540,\\\"_22\\\":542,\\\"_24\\\":543,\\\"_26\\\":34,\\\"_27\\\":544},{\\\"_18\\\":541},\\\"createRemixStub\\\",\\\"utils/create-remix-stub.md\\\",\\\"utils/create-remix-stub\\\",[],{\\\"_16\\\":546,\\\"_22\\\":548,\\\"_24\\\":549,\\\"_26\\\":34,\\\"_27\\\":550},{\\\"_18\\\":547,\\\"_169\\\":10},\\\"data\\\",\\\"utils/data.md\\\",\\\"utils/data\\\",[],{\\\"_16\\\":552,\\\"_22\\\":554,\\\"_24\\\":555,\\\"_26\\\":34,\\\"_27\\\":556},{\\\"_18\\\":553,\\\"_169\\\":10},\\\"defer\\\",\\\"utils/defer.md\\\",\\\"utils/defer\\\",[],{\\\"_16\\\":558,\\\"_22\\\":560,\\\"_24\\\":561,\\\"_26\\\":34,\\\"_27\\\":562},{\\\"_18\\\":559,\\\"_169\\\":10},\\\"isRouteErrorResponse\\\",\\\"utils/is-route-error-response.md\\\",\\\"utils/is-route-error-response\\\",[],{\\\"_16\\\":564,\\\"_22\\\":566,\\\"_24\\\":567,\\\"_26\\\":34,\\\"_27\\\":568},{\\\"_18\\\":565,\\\"_169\\\":10},\\\"json\\\",\\\"utils/json.md\\\",\\\"utils/json\\\",[],{\\\"_16\\\":570,\\\"_22\\\":572,\\\"_24\\\":573,\\\"_26\\\":34,\\\"_27\\\":574},{\\\"_18\\\":571},\\\"unstable_parseMultipartFormData\\\",\\\"utils/parse-multipart-form-data.md\\\",\\\"utils/parse-multipart-form-data\\\",[],{\\\"_16\\\":576,\\\"_22\\\":578,\\\"_24\\\":579,\\\"_26\\\":34,\\\"_27\\\":580},{\\\"_18\\\":577,\\\"_169\\\":10},\\\"redirect\\\",\\\"utils/redirect.md\\\",\\\"utils/redirect\\\",[],{\\\"_16\\\":582,\\\"_22\\\":584,\\\"_24\\\":585,\\\"_26\\\":34,\\\"_27\\\":586},{\\\"_18\\\":583,\\\"_169\\\":10},\\\"redirectDocument\\\",\\\"utils/redirectDocument.md\\\",\\\"utils/redirectDocument\\\",[],{\\\"_16\\\":588,\\\"_22\\\":590,\\\"_24\\\":591,\\\"_26\\\":34,\\\"_27\\\":592},{\\\"_18\\\":589,\\\"_169\\\":10},\\\"replace\\\",\\\"utils/replace.md\\\",\\\"utils/replace\\\",[],{\\\"_16\\\":594,\\\"_22\\\":596,\\\"_24\\\":597,\\\"_26\\\":34,\\\"_27\\\":598},{\\\"_18\\\":595},\\\"Sessions\\\",\\\"utils/sessions.md\\\",\\\"utils/sessions\\\",[],{\\\"_16\\\":600,\\\"_22\\\":602,\\\"_24\\\":603,\\\"_26\\\":34,\\\"_27\\\":604},{\\\"_18\\\":601,\\\"_169\\\":10},\\\"unstable_createFileUploadHandler\\\",\\\"utils/unstable-create-file-upload-handler.md\\\",\\\"utils/unstable-create-file-upload-handler\\\",[],{\\\"_16\\\":606,\\\"_22\\\":608,\\\"_24\\\":609,\\\"_26\\\":34,\\\"_27\\\":610},{\\\"_18\\\":607,\\\"_169\\\":10},\\\"unstable_createMemoryUploadHandler\\\",\\\"utils/unstable-create-memory-upload-handler.md\\\",\\\"utils/unstable-create-memory-upload-handler\\\",[],{\\\"_16\\\":612,\\\"_22\\\":614,\\\"_24\\\":615,\\\"_26\\\":10,\\\"_27\\\":616},{\\\"_18\\\":613,\\\"_20\\\":118},\\\"Styling\\\",\\\"styling/index.md\\\",\\\"styling\\\",[617,623,629,635,641,647,653,659],{\\\"_16\\\":618,\\\"_22\\\":620,\\\"_24\\\":621,\\\"_26\\\":34,\\\"_27\\\":622},{\\\"_18\\\":619},\\\"CSS Bundling\\\",\\\"styling/bundling.md\\\",\\\"styling/bundling\\\",[],{\\\"_16\\\":624,\\\"_22\\\":626,\\\"_24\\\":627,\\\"_26\\\":34,\\\"_27\\\":628},{\\\"_18\\\":625},\\\"Regular CSS\\\",\\\"styling/css.md\\\",\\\"styling/css\\\",[],{\\\"_16\\\":630,\\\"_22\\\":632,\\\"_24\\\":633,\\\"_26\\\":34,\\\"_27\\\":634},{\\\"_18\\\":631},\\\"CSS Imports\\\",\\\"styling/css-imports.md\\\",\\\"styling/css-imports\\\",[],{\\\"_16\\\":636,\\\"_22\\\":638,\\\"_24\\\":639,\\\"_26\\\":34,\\\"_27\\\":640},{\\\"_18\\\":637},\\\"CSS in JS\\\",\\\"styling/css-in-js.md\\\",\\\"styling/css-in-js\\\",[],{\\\"_16\\\":642,\\\"_22\\\":644,\\\"_24\\\":645,\\\"_26\\\":34,\\\"_27\\\":646},{\\\"_18\\\":643},\\\"CSS Modules\\\",\\\"styling/css-modules.md\\\",\\\"styling/css-modules\\\",[],{\\\"_16\\\":648,\\\"_22\\\":650,\\\"_24\\\":651,\\\"_26\\\":34,\\\"_27\\\":652},{\\\"_18\\\":649},\\\"PostCSS\\\",\\\"styling/postcss.md\\\",\\\"styling/postcss\\\",[],{\\\"_16\\\":654,\\\"_22\\\":656,\\\"_24\\\":657,\\\"_26\\\":34,\\\"_27\\\":658},{\\\"_18\\\":655},\\\"Tailwind\\\",\\\"styling/tailwind.md\\\",\\\"styling/tailwind\\\",[],{\\\"_16\\\":660,\\\"_22\\\":662,\\\"_24\\\":663,\\\"_26\\\":34,\\\"_27\\\":664},{\\\"_18\\\":661},\\\"Vanilla Extract\\\",\\\"styling/vanilla-extract.md\\\",\\\"styling/vanilla-extract\\\",[],{\\\"_16\\\":666,\\\"_22\\\":668,\\\"_24\\\":669,\\\"_26\\\":10,\\\"_27\\\":670},{\\\"_18\\\":667,\\\"_20\\\":132},\\\"Other API\\\",\\\"other-api/index.md\\\",\\\"other-api\\\",[671,677,683,689,695,701],{\\\"_16\\\":672,\\\"_22\\\":674,\\\"_24\\\":675,\\\"_26\\\":34,\\\"_27\\\":676},{\\\"_18\\\":673,\\\"_20\\\":39,\\\"_379\\\":34},\\\"@remix-run/dev CLI\\\",\\\"other-api/dev.md\\\",\\\"other-api/dev\\\",[],{\\\"_16\\\":678,\\\"_22\\\":680,\\\"_24\\\":681,\\\"_26\\\":34,\\\"_27\\\":682},{\\\"_18\\\":679,\\\"_20\\\":46},\\\"@remix-run/{adapter}\\\",\\\"other-api/adapter.md\\\",\\\"other-api/adapter\\\",[],{\\\"_16\\\":684,\\\"_22\\\":686,\\\"_24\\\":687,\\\"_26\\\":34,\\\"_27\\\":688},{\\\"_18\\\":685,\\\"_20\\\":46},\\\"@remix-run/serve\\\",\\\"other-api/serve.md\\\",\\\"other-api/serve\\\",[],{\\\"_16\\\":690,\\\"_22\\\":692,\\\"_24\\\":693,\\\"_26\\\":34,\\\"_27\\\":694},{\\\"_18\\\":691},\\\"create-remix (CLI)\\\",\\\"other-api/create-remix.md\\\",\\\"other-api/create-remix\\\",[],{\\\"_16\\\":696,\\\"_22\\\":698,\\\"_24\\\":699,\\\"_26\\\":34,\\\"_27\\\":700},{\\\"_18\\\":697},\\\"@remix-run/node\\\",\\\"other-api/node.md\\\",\\\"other-api/node\\\",[],{\\\"_16\\\":702,\\\"_22\\\":704,\\\"_24\\\":705,\\\"_26\\\":34,\\\"_27\\\":706},{\\\"_18\\\":703},\\\"@remix-run/testing\\\",\\\"other-api/testing.md\\\",\\\"other-api/testing\\\",[],{\\\"_16\\\":708,\\\"_22\\\":711,\\\"_24\\\":712,\\\"_26\\\":10,\\\"_27\\\":713},{\\\"_18\\\":709,\\\"_20\\\":710},\\\"Guides\\\",10,\\\"guides/index.md\\\",\\\"guides\\\",[714,720,726,732,738,744,750,756,762,769,775,782,788,794,800,806,812,818,825,831,837,843,849,855,861,867,874,881,887,893,899,905,911,917,923,930,937,943],{\\\"_16\\\":715,\\\"_22\\\":717,\\\"_24\\\":718,\\\"_26\\\":34,\\\"_27\\\":719},{\\\"_18\\\":716},\\\"Accessibility\\\",\\\"guides/accessibility.md\\\",\\\"guides/accessibility\\\",[],{\\\"_16\\\":721,\\\"_22\\\":723,\\\"_24\\\":724,\\\"_26\\\":34,\\\"_27\\\":725},{\\\"_18\\\":722},\\\"Development Strategy\\\",\\\"guides/api-development-strategy.md\\\",\\\"guides/api-development-strategy\\\",[],{\\\"_16\\\":727,\\\"_22\\\":729,\\\"_24\\\":730,\\\"_26\\\":34,\\\"_27\\\":731},{\\\"_18\\\":728},\\\"API Routes\\\",\\\"guides/api-routes.md\\\",\\\"guides/api-routes\\\",[],{\\\"_16\\\":733,\\\"_22\\\":735,\\\"_24\\\":736,\\\"_26\\\":34,\\\"_27\\\":737},{\\\"_18\\\":734,\\\"_169\\\":10},\\\"Backend For Frontend\\\",\\\"guides/bff.md\\\",\\\"guides/bff\\\",[],{\\\"_16\\\":739,\\\"_22\\\":741,\\\"_24\\\":742,\\\"_26\\\":34,\\\"_27\\\":743},{\\\"_18\\\":740},\\\"Breadcrumbs Guide\\\",\\\"guides/breadcrumbs.md\\\",\\\"guides/breadcrumbs\\\",[],{\\\"_16\\\":745,\\\"_22\\\":747,\\\"_24\\\":748,\\\"_26\\\":34,\\\"_27\\\":749},{\\\"_18\\\":746},\\\"Browser Support\\\",\\\"guides/browser-support.md\\\",\\\"guides/browser-support\\\",[],{\\\"_16\\\":751,\\\"_22\\\":753,\\\"_24\\\":754,\\\"_26\\\":34,\\\"_27\\\":755},{\\\"_18\\\":752},\\\"Client Data\\\",\\\"guides/client-data.md\\\",\\\"guides/client-data\\\",[],{\\\"_16\\\":757,\\\"_22\\\":759,\\\"_24\\\":760,\\\"_26\\\":34,\\\"_27\\\":761},{\\\"_18\\\":758},\\\"Module Constraints\\\",\\\"guides/constraints.md\\\",\\\"guides/constraints\\\",[],{\\\"_16\\\":763,\\\"_22\\\":766,\\\"_24\\\":767,\\\"_26\\\":34,\\\"_27\\\":768},{\\\"_18\\\":764,\\\"_53\\\":765},\\\"Contributing\\\",\\\"Thank you for contributing to Remix! Here's everything you need to know before you open a pull request.\\\",\\\"guides/contributing.md\\\",\\\"guides/contributing\\\",[],{\\\"_16\\\":770,\\\"_22\\\":772,\\\"_24\\\":773,\\\"_26\\\":34,\\\"_27\\\":774},{\\\"_18\\\":771},\\\"CSS Files\\\",\\\"guides/css-files.md\\\",\\\"guides/css-files\\\",[],{\\\"_16\\\":776,\\\"_22\\\":779,\\\"_24\\\":780,\\\"_26\\\":34,\\\"_27\\\":781},{\\\"_18\\\":777,\\\"_53\\\":778},\\\"Data Loading\\\",\\\"One of the primary features of Remix is simplifying interactions with the server to get data into components. This document will help you get the most out of data loading in Remix.\\\",\\\"guides/data-loading.md\\\",\\\"guides/data-loading\\\",[],{\\\"_16\\\":783,\\\"_22\\\":785,\\\"_24\\\":786,\\\"_26\\\":34,\\\"_27\\\":787},{\\\"_18\\\":784},\\\"Data Writes\\\",\\\"guides/data-writes.md\\\",\\\"guides/data-writes\\\",[],{\\\"_16\\\":789,\\\"_22\\\":791,\\\"_24\\\":792,\\\"_26\\\":34,\\\"_27\\\":793},{\\\"_18\\\":790},\\\"Dependency optimization\\\",\\\"guides/dependency-optimization.md\\\",\\\"guides/dependency-optimization\\\",[],{\\\"_16\\\":795,\\\"_22\\\":797,\\\"_24\\\":798,\\\"_26\\\":34,\\\"_27\\\":799},{\\\"_18\\\":796,\\\"_169\\\":10},\\\"Deployment\\\",\\\"guides/deployment.md\\\",\\\"guides/deployment\\\",[],{\\\"_16\\\":801,\\\"_22\\\":803,\\\"_24\\\":804,\\\"_26\\\":34,\\\"_27\\\":805},{\\\"_18\\\":802,\\\"_169\\\":10},\\\"Disabling JavaScript\\\",\\\"guides/disabling-javascript.md\\\",\\\"guides/disabling-javascript\\\",[],{\\\"_16\\\":807,\\\"_22\\\":809,\\\"_24\\\":810,\\\"_26\\\":34,\\\"_27\\\":811},{\\\"_18\\\":808},\\\"Environment Variables\\\",\\\"guides/envvars.md\\\",\\\"guides/envvars\\\",[],{\\\"_16\\\":813,\\\"_22\\\":815,\\\"_24\\\":816,\\\"_26\\\":34,\\\"_27\\\":817},{\\\"_18\\\":814},\\\"Error Handling\\\",\\\"guides/errors.md\\\",\\\"guides/errors\\\",[],{\\\"_16\\\":819,\\\"_22\\\":822,\\\"_24\\\":823,\\\"_26\\\":34,\\\"_27\\\":824},{\\\"_18\\\":820,\\\"_53\\\":821},\\\"FAQs\\\",\\\"Frequently Asked Questions about Remix\\\",\\\"guides/faq.md\\\",\\\"guides/faq\\\",[],{\\\"_16\\\":826,\\\"_22\\\":828,\\\"_24\\\":829,\\\"_26\\\":34,\\\"_27\\\":830},{\\\"_18\\\":827},\\\"File Uploads\\\",\\\"guides/file-uploads.md\\\",\\\"guides/file-uploads\\\",[],{\\\"_16\\\":832,\\\"_22\\\":834,\\\"_24\\\":835,\\\"_26\\\":34,\\\"_27\\\":836},{\\\"_18\\\":833},\\\"Form Validation\\\",\\\"guides/form-validation.md\\\",\\\"guides/form-validation\\\",[],{\\\"_16\\\":838,\\\"_22\\\":840,\\\"_24\\\":841,\\\"_26\\\":34,\\\"_27\\\":842},{\\\"_18\\\":839},\\\"Gotchas\\\",\\\"guides/gotchas.md\\\",\\\"guides/gotchas\\\",[],{\\\"_16\\\":844,\\\"_22\\\":846,\\\"_24\\\":847,\\\"_26\\\":34,\\\"_27\\\":848},{\\\"_18\\\":845,\\\"_169\\\":10},\\\"Index Query Param\\\",\\\"guides/index-query-param.md\\\",\\\"guides/index-query-param\\\",[],{\\\"_16\\\":850,\\\"_22\\\":852,\\\"_24\\\":853,\\\"_26\\\":34,\\\"_27\\\":854},{\\\"_18\\\":851},\\\"Lazy Route Discovery\\\",\\\"guides/lazy-route-discovery.md\\\",\\\"guides/lazy-route-discovery\\\",[],{\\\"_16\\\":856,\\\"_22\\\":858,\\\"_24\\\":859,\\\"_26\\\":34,\\\"_27\\\":860},{\\\"_18\\\":857},\\\"Local TLS\\\",\\\"guides/local-tls.md\\\",\\\"guides/local-tls\\\",[],{\\\"_16\\\":862,\\\"_22\\\":864,\\\"_24\\\":865,\\\"_26\\\":34,\\\"_27\\\":866},{\\\"_18\\\":863},\\\"Manual Dev Server\\\",\\\"guides/manual-mode.md\\\",\\\"guides/manual-mode\\\",[],{\\\"_16\\\":868,\\\"_22\\\":871,\\\"_24\\\":872,\\\"_26\\\":34,\\\"_27\\\":873},{\\\"_18\\\":869,\\\"_53\\\":870},\\\"MDX\\\",\\\"Remix makes integrating MDX into your project a breeze with built in routes and \\\\\\\"import\\\\\\\" support.\\\",\\\"guides/mdx.md\\\",\\\"guides/mdx\\\",[],{\\\"_16\\\":875,\\\"_22\\\":878,\\\"_24\\\":879,\\\"_26\\\":34,\\\"_27\\\":880},{\\\"_18\\\":876,\\\"_53\\\":877},\\\"Migrating from React Router\\\",\\\"Migrating your React Router app to Remix can be done all at once or in stages. This guide will walk you through an iterative approach to get your app running quickly.\\\",\\\"guides/migrating-react-router-app.md\\\",\\\"guides/migrating-react-router-app\\\",[],{\\\"_16\\\":882,\\\"_22\\\":884,\\\"_24\\\":885,\\\"_26\\\":34,\\\"_27\\\":886},{\\\"_18\\\":883},\\\"Not Found Handling\\\",\\\"guides/not-found.md\\\",\\\"guides/not-found\\\",[],{\\\"_16\\\":888,\\\"_22\\\":890,\\\"_24\\\":891,\\\"_26\\\":34,\\\"_27\\\":892},{\\\"_18\\\":889},\\\"Performance\\\",\\\"guides/performance.md\\\",\\\"guides/performance\\\",[],{\\\"_16\\\":894,\\\"_22\\\":896,\\\"_24\\\":897,\\\"_26\\\":34,\\\"_27\\\":898},{\\\"_18\\\":895},\\\"Presets\\\",\\\"guides/presets.md\\\",\\\"guides/presets\\\",[],{\\\"_16\\\":900,\\\"_22\\\":902,\\\"_24\\\":903,\\\"_26\\\":34,\\\"_27\\\":904},{\\\"_18\\\":901},\\\"Resource Routes\\\",\\\"guides/resource-routes.md\\\",\\\"guides/resource-routes\\\",[],{\\\"_16\\\":906,\\\"_22\\\":908,\\\"_24\\\":909,\\\"_26\\\":34,\\\"_27\\\":910},{\\\"_18\\\":907},\\\"Server Bundles\\\",\\\"guides/server-bundles.md\\\",\\\"guides/server-bundles\\\",[],{\\\"_16\\\":912,\\\"_22\\\":914,\\\"_24\\\":915,\\\"_26\\\":34,\\\"_27\\\":916},{\\\"_18\\\":913},\\\"Single Fetch\\\",\\\"guides/single-fetch.md\\\",\\\"guides/single-fetch\\\",[],{\\\"_16\\\":918,\\\"_22\\\":920,\\\"_24\\\":921,\\\"_26\\\":34,\\\"_27\\\":922},{\\\"_18\\\":919},\\\"SPA Mode\\\",\\\"guides/spa-mode.md\\\",\\\"guides/spa-mode\\\",[],{\\\"_16\\\":924,\\\"_22\\\":927,\\\"_24\\\":928,\\\"_26\\\":34,\\\"_27\\\":929},{\\\"_18\\\":925,\\\"_53\\\":926},\\\"Streaming\\\",\\\"When, why, and how to stream with React 18 and Remix's deferred API.\\\",\\\"guides/streaming.md\\\",\\\"guides/streaming\\\",[],{\\\"_16\\\":931,\\\"_22\\\":934,\\\"_24\\\":935,\\\"_26\\\":34,\\\"_27\\\":936},{\\\"_18\\\":932,\\\"_53\\\":933},\\\"Templates\\\",\\\"The quickest way to get rocking and rolling with Remix\\\",\\\"guides/templates.md\\\",\\\"guides/templates\\\",[],{\\\"_16\\\":938,\\\"_22\\\":940,\\\"_24\\\":941,\\\"_26\\\":34,\\\"_27\\\":942},{\\\"_18\\\":939,\\\"_169\\\":10},\\\"TypeScript\\\",\\\"guides/typescript.md\\\",\\\"guides/typescript\\\",[],{\\\"_16\\\":944,\\\"_22\\\":946,\\\"_24\\\":947,\\\"_26\\\":34,\\\"_27\\\":948},{\\\"_18\\\":945},\\\"Vite\\\",\\\"guides/vite.md\\\",\\\"guides/vite\\\",[],\\\"routes/docs.$\\\",{\\\"_951\\\":952},\\\"doc\\\",{\\\"_16\\\":953,\\\"_22\\\":954,\\\"_955\\\":956,\\\"_24\\\":957,\\\"_958\\\":959,\\\"_27\\\":1004},{\\\"_18\\\":61,\\\"_20\\\":62},\\\"docs/start/future-flags.md\\\",\\\"html\\\",\\\"\\u003ch1 id=\\\\\\\"future-flags-and-deprecations\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#future-flags-and-deprecations\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eFuture Flags and Deprecations\\u003c/h1\\u003e\\\\n\\u003cp\\u003eThis guide walks you through the process of adopting future flags in your Remix app. By following this strategy, you will be able to upgrade to the next major version of Remix with minimal changes. To read more about future flags, see \\u003ca href=\\\\\\\"../guides/api-development-strategy\\\\\\\"\\u003eDevelopment Strategy\\u003c/a\\u003e.\\u003c/p\\u003e\\\\n\\u003cp\\u003eWe highly recommend you make a commit after each step and ship it instead of doing everything all at once. Most flags can be adopted in any order, with exceptions noted below.\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"update-to-latest-v2x\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#update-to-latest-v2x\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eUpdate to latest v2.x\\u003c/h2\\u003e\\\\n\\u003cp\\u003eFirst update to the latest minor version of v2.x to have the latest future flags. You will likely see a number of deprecation warnings as you upgrade, which we'll cover below.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eUpdate to latest v2\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\"\\u003e\\u003cpre data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003enpm\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003einstall\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/{dev,react,node,etc.}@2\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003ch2 id=\\\\\\\"remove-installglobals\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#remove-installglobals\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eRemove \\u003ccode\\u003einstallGlobals\\u003c/code\\u003e\\u003c/h2\\u003e\\\\n\\u003cp\\u003e\\u003cstrong\\u003eBackground\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003ePreviously Remix required a \\u003ccode\\u003efetch\\u003c/code\\u003e polyfill to be installed. This was achieved by calling \\u003ccode\\u003einstallGlobals()\\u003c/code\\u003e.\\u003c/p\\u003e\\\\n\\u003cp\\u003eThe next major version requires a minimum of Node 20 to take advantage of the built-in \\u003ccode\\u003efetch\\u003c/code\\u003e support.\\u003c/p\\u003e\\\\n\\u003cp\\u003eNote: if you are using Miniflare/Cloudflare worker with your remix project, ensure your \\u003ca href=\\\\\\\"https://developers.cloudflare.com/workers/configuration/compatibility-dates\\\\\\\"\\u003ecompatibility flag\\u003c/a\\u003e is set to \\u003ccode\\u003e2023-03-01\\u003c/code\\u003e or later as well.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eUpdate to Node 20+\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eIt is recommended that you upgrade to the latest even-numbered version of Node LTS.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eRemove \\u003ccode\\u003einstallGlobals\\u003c/code\\u003e\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"vite.config.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"diff\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"vite.config.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"diff\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003eimport { vitePlugin as remix } from \\\\\\\"@remix-run/dev\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003eimport { defineConfig } from \\\\\\\"vite\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e-\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003einstallGlobals();\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003eexport default defineConfig({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e plugins: [remix()],\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e});\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003ch2 id=\\\\\\\"adopt-the-vite-plugin\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#adopt-the-vite-plugin\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eAdopt the Vite Plugin\\u003c/h2\\u003e\\\\n\\u003cp\\u003e\\u003cstrong\\u003eBackground\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eRemix no longer uses its own, closed compiler (now referred to as the \\\\\\\"Classic Compiler\\\\\\\") and instead uses \\u003ca href=\\\\\\\"https://vitejs.dev\\\\\\\"\\u003eVite\\u003c/a\\u003e. Vite is a powerful, performant and extensible development environment for JavaScript projects. \\u003ca href=\\\\\\\"../guides/vite\\\\\\\"\\u003eView the Vite docs\\u003c/a\\u003e for more information on performance, troubleshooting, etc.\\u003c/p\\u003e\\\\n\\u003cp\\u003eWhile this is not a future flag, new features and some feature flags are only available in the Vite plugin, and the Classic Compiler will be removed in the next version of Remix.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eInstall Vite\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\"\\u003e\\u003cpre data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003enpm\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003einstall\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e-D\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003evite\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003e\\u003cstrong\\u003eUpdate your Code\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eReplace \\u003ccode\\u003eremix.config.js\\u003c/code\\u003e with \\u003ccode\\u003evite.config.ts\\u003c/code\\u003e at the root of your Remix app\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"vite.config.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"vite.config.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003evitePlugin\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eas\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eremix\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/dev\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003edefineConfig\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003evite\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003edefault\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003edefineConfig\\u003c/span\\u003e({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e plugins: [\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eremix\\u003c/span\\u003e()],\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e});\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eThe subset of \\u003ca href=\\\\\\\"../file-conventions/vite-config\\\\\\\"\\u003esupported Remix config options\\u003c/a\\u003e should be passed directly to the plugin:\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"vite.config.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"vite.config.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003edefault\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003edefineConfig\\u003c/span\\u003e({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e plugins: [\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eremix\\u003c/span\\u003e({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e ignoredRouteFiles: [\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e**/*.css\\u003c/span\\u003e\\\\\\\"],\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e }),\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e ],\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e});\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eAdd \\u003ccode\\u003eunstable_optimizeDeps\\u003c/code\\u003e (optional)\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eMany users found that automatically \\u003ca href=\\\\\\\"../guides/dependency-optimization\\\\\\\"\\u003eoptimizing dependencies\\u003c/a\\u003e helped them more easily adopt the Vite plugin. For this reason we added the \\u003ccode\\u003eunstable_optimizeDeps\\u003c/code\\u003e flag to the Vite plugin.\\u003c/p\\u003e\\\\n\\u003cp\\u003eThis flag will remain in an \\\\\\\"unstable\\\\\\\" state until React Router v7, so it is not critical that you adopt this in your Remix v2 app before upgrading to React Router v7.\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"vite.config.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"vite.config.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003edefault\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003edefineConfig\\u003c/span\\u003e({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e plugins: [\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eremix\\u003c/span\\u003e({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e future: {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e unstable_optimizeDeps: \\u003cspan style=\\\\\\\"color: var(--base09)\\\\\\\"\\u003etrue\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e },\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e }),\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e ],\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e});\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eRemove \\u003ccode\\u003e\\u0026#x3C;LiveReload/\\u003e\\u003c/code\\u003e, keep \\u003ccode\\u003e\\u0026#x3C;Scripts /\\u003e\\u003c/code\\u003e\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"diff\\\\\\\"\\u003e\\u003cpre data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"diff\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e import {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e-\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003e LiveReload,\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e Outlet,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e Scripts,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e }\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e export default function App() {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e return (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e \\u0026#x3C;html\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e \\u0026#x3C;head\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e \\u0026#x3C;/head\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e \\u0026#x3C;body\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e \\u0026#x3C;Outlet /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e-\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003e \\u0026#x3C;LiveReload /\\u003e\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e \\u0026#x3C;Scripts /\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e \\u0026#x3C;/body\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e \\u0026#x3C;/html\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"18\\\\\\\"\\u003e )\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"19\\\\\\\"\\u003e }\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eUpdate \\u003ccode\\u003etsconfig.json\\u003c/code\\u003e\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eUpdate the \\u003ccode\\u003etypes\\u003c/code\\u003e field in \\u003ccode\\u003etsconfig.json\\u003c/code\\u003e and make sure \\u003ccode\\u003eskipLibCheck\\u003c/code\\u003e, \\u003ccode\\u003emodule\\u003c/code\\u003e, and \\u003ccode\\u003emoduleResolution\\u003c/code\\u003e are all set correctly.\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"tsconfig.json\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"json\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"tsconfig.json\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"json\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e{\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ecompilerOptions\\u003c/span\\u003e\\\\\\\": {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003etypes\\u003c/span\\u003e\\\\\\\": [\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/node\\u003c/span\\u003e\\\\\\\", \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003evite/client\\u003c/span\\u003e\\\\\\\"],\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eskipLibCheck\\u003c/span\\u003e\\\\\\\": \\u003cspan style=\\\\\\\"color: var(--base09)\\\\\\\"\\u003etrue\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003emodule\\u003c/span\\u003e\\\\\\\": \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eESNext\\u003c/span\\u003e\\\\\\\",\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003emoduleResolution\\u003c/span\\u003e\\\\\\\": \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eBundler\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e }\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eUpdate/remove \\u003ccode\\u003eremix.env.d.ts\\u003c/code\\u003e\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eRemove the following type declarations in \\u003ccode\\u003eremix.env.d.ts\\u003c/code\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"remix.env.d.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"diff\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"remix.env.d.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"diff\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e-\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003e /// \\u0026#x3C;reference types=\\\\\\\"@remix-run/dev\\\\\\\" /\\u003e\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e-\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003e /// \\u0026#x3C;reference types=\\\\\\\"@remix-run/node\\\\\\\" /\\u003e\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eIf \\u003ccode\\u003eremix.env.d.ts\\u003c/code\\u003e is now empty, delete it\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\"\\u003e\\u003cpre data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003erm\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eremix.env.d.ts\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003e\\u003cstrong\\u003eConfigure path aliases\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eVite does not provide any path aliases by default. If you were relying on this feature, such as defining \\u003ccode\\u003e~\\u003c/code\\u003e as an alias for the \\u003ccode\\u003eapp\\u003c/code\\u003e directory, you can install the \\u003ca href=\\\\\\\"https://github.com/aleclarson/vite-tsconfig-paths\\\\\\\"\\u003evite-tsconfig-paths\\u003c/a\\u003e plugin to automatically resolve path aliases from your \\u003ccode\\u003etsconfig.json\\u003c/code\\u003e in Vite, matching the behavior of the Remix compiler:\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eInstall \\u003ccode\\u003evite-tsconfig-paths\\u003c/code\\u003e\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\"\\u003e\\u003cpre data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003enpm\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003einstall\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e-D\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003evite-tsconfig-paths\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eAdd \\u003ccode\\u003evite-tsconfig-paths\\u003c/code\\u003e to your Vite config\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"vite.config.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"vite.config.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003evitePlugin\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eas\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eremix\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/dev\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003edefineConfig\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003evite\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003etsconfigPaths\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003evite-tsconfig-paths\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003edefault\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003edefineConfig\\u003c/span\\u003e({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e plugins: [\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eremix\\u003c/span\\u003e(), \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003etsconfigPaths\\u003c/span\\u003e()],\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e});\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003e\\u003cstrong\\u003eRemove \\u003ccode\\u003e@remix-run/css-bundle\\u003c/code\\u003e\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eVite has built-in support for CSS side effect imports, PostCSS and CSS Modules, among other CSS bundling features. The Remix Vite plugin automatically attaches bundled CSS to the relevant routes.\\u003c/p\\u003e\\\\n\\u003cp\\u003eThe \\u003cnobr\\u003e\\u003ca href=\\\\\\\"../styling/bundling\\\\\\\"\\u003e\\u003ccode\\u003e@remix-run/css-bundle\\u003c/code\\u003e\\u003c/a\\u003e\\u003c/nobr\\u003e package is redundant when using Vite since its \\u003ccode\\u003ecssBundleHref\\u003c/code\\u003e export will always be \\u003ccode\\u003eundefined\\u003c/code\\u003e.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eUninstall \\u003ccode\\u003e@remix-run/css-bundle\\u003c/code\\u003e\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\"\\u003e\\u003cpre data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003enpm\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003euninstall\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/css-bundle\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eRemove references to \\u003ccode\\u003ecssBundleHref\\u003c/code\\u003e\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/root.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"diff\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/root.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"diff\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e-\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003e import { cssBundleHref } from \\\\\\\"@remix-run/css-bundle\\\\\\\";\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e import type { LinksFunction } from \\\\\\\"@remix-run/node\\\\\\\"; // or cloudflare/deno\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e export const links: LinksFunction = () =\\u003e [\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e-\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003e ...(cssBundleHref\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e-\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003e ? [{ rel: \\\\\\\"stylesheet\\\\\\\", href: cssBundleHref }]\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e-\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003e : []),\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e // ...\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e ];\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003e\\u003cstrong\\u003eFix up CSS imports referenced in \\u003ccode\\u003elinks\\u003c/code\\u003e\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eIf you are \\u003ca href=\\\\\\\"../styling/css\\\\\\\"\\u003ereferencing CSS in a \\u003ccode\\u003elinks\\u003c/code\\u003e function\\u003c/a\\u003e, you'll need to update the corresponding CSS imports to use \\u003ca href=\\\\\\\"https://vitejs.dev/guide/assets.html#explicit-url-imports\\\\\\\"\\u003eVite's explicit \\u003ccode\\u003e?url\\u003c/code\\u003e import syntax.\\u003c/a\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eAdd \\u003ccode\\u003e?url\\u003c/code\\u003e to CSS imports used in \\u003ccode\\u003elinks\\u003c/code\\u003e\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"diff\\\\\\\"\\u003e\\u003cpre data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"diff\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e-\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eimport styles from \\\\\\\"~/styles/dashboard.css\\\\\\\";\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e+\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eimport styles from \\\\\\\"~/styles/dashboard.css?url\\\\\\\";\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003eexport const links = () =\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e return [\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e { rel: \\\\\\\"stylesheet\\\\\\\", href: styles }\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e ];\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003e\\u003cstrong\\u003eMigrate Tailwind CSS or Vanilla Extract\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eIf you are using Tailwind CSS or Vanilla Extract, see the \\u003ca href=\\\\\\\"../guides/vite#enable-tailwind-via-postcss\\\\\\\"\\u003efull migration guide\\u003c/a\\u003e.\\u003c/p\\u003e\\\\n\\u003cp\\u003e\\u003cstrong\\u003eMigrate from Remix App Server\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eUpdate your \\u003ccode\\u003edev\\u003c/code\\u003e, \\u003ccode\\u003ebuild\\u003c/code\\u003e and \\u003ccode\\u003estart\\u003c/code\\u003e scripts\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"package.json\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"json\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"package.json\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"json\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e{\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003escripts\\u003c/span\\u003e\\\\\\\": {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003edev\\u003c/span\\u003e\\\\\\\": \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eremix vite:dev\\u003c/span\\u003e\\\\\\\",\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ebuild\\u003c/span\\u003e\\\\\\\": \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eremix vite:build\\u003c/span\\u003e\\\\\\\",\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003estart\\u003c/span\\u003e\\\\\\\": \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eremix-serve ./build/server/index.js\\u003c/span\\u003e\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e }\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eConfigure your Vite dev server port (optional)\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"vite.config.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"javascript\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"vite.config.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"javascript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003edefault\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003edefineConfig\\u003c/span\\u003e({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e server: {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e port: \\u003cspan style=\\\\\\\"color: var(--base09)\\\\\\\"\\u003e3000\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e },\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e plugins: [\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eremix\\u003c/span\\u003e()],\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e});\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003e\\u003cstrong\\u003eMigrate a custom server\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eIf you are migrating a customer server or Cloudflare Functions, see the \\u003ca href=\\\\\\\"../guides/vite#migrating-a-custom-server\\\\\\\"\\u003efull migration guide\\u003c/a\\u003e.\\u003c/p\\u003e\\\\n\\u003cp\\u003e\\u003cstrong\\u003eMigrate MDX routes\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eIf you're using \\u003ca href=\\\\\\\"https://mdxjs.com\\\\\\\"\\u003eMDX\\u003c/a\\u003e, you should use the official \\u003ca href=\\\\\\\"https://mdxjs.com/packages/rollup\\\\\\\"\\u003eMDX Rollup plugin\\u003c/a\\u003e. See the \\u003ca href=\\\\\\\"../guides/vite#add-mdx-plugin\\\\\\\"\\u003efull migration guide\\u003c/a\\u003e for a step-by-step walkthrough.\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"v3_fetcherpersist\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#v3_fetcherpersist\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003ev3_fetcherPersist\\u003c/h2\\u003e\\\\n\\u003cp\\u003e\\u003cstrong\\u003eBackground\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eThe fetcher lifecycle is now based on when it returns to an idle state rather than when its owner component unmounts: \\u003ca href=\\\\\\\"https://github.com/remix-run/remix/discussions/7698\\\\\\\"\\u003eView the RFC\\u003c/a\\u003e for more information.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eEnable the Flag\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"vite.config.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"vite.config.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eremix\\u003c/span\\u003e({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e future: {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e v3_fetcherPersist: \\u003cspan style=\\\\\\\"color: var(--base09)\\\\\\\"\\u003etrue\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e },\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e});\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003e\\u003cstrong\\u003eUpdate your Code\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eIt's unlikely to affect your app. You may want to check any usage of \\u003ccode\\u003euseFetchers\\u003c/code\\u003e as they may persist longer than they did before. Depending on what you're doing, you may render something longer than before.\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"v3_relativesplatpath\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#v3_relativesplatpath\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003ev3_relativeSplatPath\\u003c/h2\\u003e\\\\n\\u003cp\\u003e\\u003cstrong\\u003eBackground\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eChanges the relative path matching and linking for multi-segment splats paths like \\u003ccode\\u003edashboard/*\\u003c/code\\u003e (vs. just \\u003ccode\\u003e*\\u003c/code\\u003e). \\u003ca href=\\\\\\\"https://github.com/remix-run/remix/blob/v2/CHANGELOG.md#futurev3_relativesplatpath\\\\\\\"\\u003eView the CHANGELOG\\u003c/a\\u003e for more information.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eEnable the Flag\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"vite.config.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"vite.config.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eremix\\u003c/span\\u003e({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e future: {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e v3_relativeSplatPath: \\u003cspan style=\\\\\\\"color: var(--base09)\\\\\\\"\\u003etrue\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e },\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e});\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003e\\u003cstrong\\u003eUpdate your Code\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eIf you have any routes with a path + a splat like \\u003ccode\\u003edashboard.$.tsx\\u003c/code\\u003e or \\u003ccode\\u003eroute(\\\\\\\"dashboard/*\\\\\\\")\\u003c/code\\u003e that have relative links like \\u003ccode\\u003e\\u0026#x3C;Link to=\\\\\\\"relative\\\\\\\"\\u003e\\u003c/code\\u003e or \\u003ccode\\u003e\\u0026#x3C;Link to=\\\\\\\"../relative\\\\\\\"\\u003e\\u003c/code\\u003e beneath it, you will need to update your code.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eSplit the route into two\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eFor any splat routes split it into a layout route and a child route with the splat:\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"diff\\\\\\\"\\u003e\\u003cpre data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"diff\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e└── routes\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e ├── _index.tsx\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e+\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e ├── dashboard.tsx\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e └── dashboard.$.tsx\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e// or\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003eroutes(defineRoutes) {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e return defineRoutes((route) =\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e route(\\\\\\\"/\\\\\\\", \\\\\\\"home/route.tsx\\\\\\\", { index: true });\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e-\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003e route(\\\\\\\"dashboard/*\\\\\\\", \\\\\\\"dashboard/route.tsx\\\\\\\")\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e+\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e route(\\\\\\\"dashboard\\\\\\\", \\\\\\\"dashboard/layout.tsx\\\\\\\", () =\\u003e {\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e+\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e route(\\\\\\\"*\\\\\\\", \\\\\\\"dashboard/route.tsx\\\\\\\");\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e });\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e });\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e},\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eUpdate relative links\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eUpdate any \\u003ccode\\u003e\\u0026#x3C;Link\\u003e\\u003c/code\\u003e elements with relative links within that route tree to include the extra \\u003ccode\\u003e..\\u003c/code\\u003e relative segment to continue linking to the same place:\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"diff\\\\\\\"\\u003e\\u003cpre data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"diff\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e// dashboard.$.tsx or dashboard/route.tsx\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003efunction Dashboard() {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e return (\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\u0026#x3C;div\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e \\u0026#x3C;h2\\u003eDashboard\\u0026#x3C;/h2\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\u0026#x3C;nav\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e-\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003e \\u0026#x3C;Link to=\\\\\\\"\\\\\\\"\\u003eDashboard Home\\u0026#x3C;/Link\\u003e\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e-\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003e \\u0026#x3C;Link to=\\\\\\\"team\\\\\\\"\\u003eTeam\\u0026#x3C;/Link\\u003e\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e-\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003e \\u0026#x3C;Link to=\\\\\\\"projects\\\\\\\"\\u003eProjects\\u0026#x3C;/Link\\u003e\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e+\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e \\u0026#x3C;Link to=\\\\\\\"../\\\\\\\"\\u003eDashboard Home\\u0026#x3C;/Link\\u003e\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e+\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e \\u0026#x3C;Link to=\\\\\\\"../team\\\\\\\"\\u003eTeam\\u0026#x3C;/Link\\u003e\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e+\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e \\u0026#x3C;Link to=\\\\\\\"../projects\\\\\\\"\\u003eProjects\\u0026#x3C;/Link\\u003e\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e \\u0026#x3C;/nav\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e \\u0026#x3C;/div\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e );\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003ch2 id=\\\\\\\"v3_throwabortreason\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#v3_throwabortreason\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003ev3_throwAbortReason\\u003c/h2\\u003e\\\\n\\u003cp\\u003e\\u003cstrong\\u003eBackground\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eWhen a server-side request is aborted, such as when a user navigates away from a page before the loader finishes, Remix will throw the \\u003ccode\\u003erequest.signal.reason\\u003c/code\\u003e instead of an error such as \\u003ccode\\u003enew Error(\\\\\\\"query() call aborted...\\\\\\\")\\u003c/code\\u003e.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eEnable the Flag\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"vite.config.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"vite.config.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eremix\\u003c/span\\u003e({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e future: {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e v3_throwAbortReason: \\u003cspan style=\\\\\\\"color: var(--base09)\\\\\\\"\\u003etrue\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e },\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e});\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003e\\u003cstrong\\u003eUpdate your Code\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eYou likely won't need to adjust any code, unless you had custom logic inside of \\u003ccode\\u003ehandleError\\u003c/code\\u003e that was matching the previous error message to differentiate it from other errors.\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"v3_lazyroutediscovery\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#v3_lazyroutediscovery\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003ev3_lazyRouteDiscovery\\u003c/h2\\u003e\\\\n\\u003cp\\u003e\\u003cstrong\\u003eBackground\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eWith this flag, Remix no longer sends the full route manifest up to the client on initial load. Instead, Remix only sends the server-rendered routes up in the manifest and then fetches the remaining routes as the user navigates around the application. Additional details are available in the \\u003ca href=\\\\\\\"../guides/lazy-route-discovery\\\\\\\"\\u003edocs\\u003c/a\\u003e and the \\u003ca href=\\\\\\\"https://remix.run/blog/fog-of-war\\\\\\\"\\u003eblog post\\u003c/a\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eEnable the Flag\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"vite.config.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"vite.config.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eremix\\u003c/span\\u003e({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e future: {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e v3_lazyRouteDiscovery: \\u003cspan style=\\\\\\\"color: var(--base09)\\\\\\\"\\u003etrue\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e },\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e});\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003e\\u003cstrong\\u003eUpdate your Code\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eYou shouldn't need to make any changes to your application code for this feature to work.\\u003c/p\\u003e\\\\n\\u003cp\\u003eYou may find some usage for the new \\u003ca href=\\\\\\\"../components/link#discover\\\\\\\"\\u003e\\u003ccode\\u003e\\u0026#x3C;Link discover\\u003e\\u003c/code\\u003e\\u003c/a\\u003e API if you wish to disable eager route discovery on certain links.\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"v3_singlefetch\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#v3_singlefetch\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003ev3_singleFetch\\u003c/h2\\u003e\\\\n\\u003cdocs-warning\\u003e\\\\n\\u003cp\\u003eThis flag requires the \\u003ca href=\\\\\\\"#adopt-the-vite-plugin\\\\\\\"\\u003eVite plugin\\u003c/a\\u003e.\\u003c/p\\u003e\\\\n\\u003c/docs-warning\\u003e\\\\n\\u003cp\\u003e\\u003cstrong\\u003eBackground\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eWith this flag, Remix uses a single fetch for data requests during client-side navigations. This simplifies data loading by treating data requests the same as document requests, eliminating the need to handle headers and caching differently. For advanced use cases, you can still opt into fine-grained revalidations. View the \\u003ca href=\\\\\\\"../guides/single-fetch\\\\\\\"\\u003e\\\\\\\"Single Fetch\\\\\\\" docs\\u003c/a\\u003e for more information.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eEnable the Flag (and the types)\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"vite.config.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"vite.config.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003evitePlugin\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eas\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eremix\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/dev\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003edefineConfig\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003evite\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003etsconfigPaths\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003evite-tsconfig-paths\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003edeclare\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003emodule\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/node\\u003c/span\\u003e\\\\\\\" {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// or cloudflare, deno, etc.\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003einterface\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eFuture\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ev3_singleFetch\\u003c/span\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e:\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0C)\\\\\\\"\\u003etrue\\u003c/span\\u003e;\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e }\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003edefault\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003edefineConfig\\u003c/span\\u003e({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e plugins: [\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eremix\\u003c/span\\u003e({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e future: {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-highlight=\\\\\\\"true\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e v3_singleFetch: \\u003cspan style=\\\\\\\"color: var(--base09)\\\\\\\"\\u003etrue\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e },\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"18\\\\\\\"\\u003e }),\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"19\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003etsconfigPaths\\u003c/span\\u003e(),\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"20\\\\\\\"\\u003e ],\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"21\\\\\\\"\\u003e});\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003e\\u003cstrong\\u003eUpdate your Code\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eYou should be able to mostly use your code as-is with the flag enabled, but the following changes should be made over time and will be required prior to the next major version.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eRemove \\u003ccode\\u003ejson()\\u003c/code\\u003e/\\u003ccode\\u003edefer()\\u003c/code\\u003e in favor of raw objects\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eSingle Fetch supports JSON objects and Promises out of the box, so you can return the raw data from your \\u003ccode\\u003eloader\\u003c/code\\u003e/\\u003ccode\\u003eaction\\u003c/code\\u003e functions:\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"diff\\\\\\\"\\u003e\\u003cpre data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"diff\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e-\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eimport { json } from \\\\\\\"@remix-run/node\\\\\\\";\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003eexport async function loader({}: LoaderFunctionArgs) {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e let tasks = await fetchTasks();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e-\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003e return json(tasks);\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e+\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e return tasks;\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"diff\\\\\\\"\\u003e\\u003cpre data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"diff\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e-\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eimport { defer } from \\\\\\\"@remix-run/node\\\\\\\";\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003eexport async function loader({}: LoaderFunctionArgs) {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e let lazyStuff = fetchLazyStuff();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e let tasks = await fetchTasks();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e-\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003e return defer({ tasks, lazyStuff });\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e+\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e return { tasks, lazyStuff };\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eIf you were using the second parameter of \\u003ccode\\u003ejson\\u003c/code\\u003e/\\u003ccode\\u003edefer\\u003c/code\\u003e to set a custom status or headers on your response, you can continue doing so via the new \\u003ccode\\u003edata\\u003c/code\\u003e API (please note that you will need a \\u003ccode\\u003eheaders\\u003c/code\\u003e export to apply those headers to Single Fetch data requests):\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"diff\\\\\\\"\\u003e\\u003cpre data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"diff\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e-\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eimport { json } from \\\\\\\"@remix-run/node\\\\\\\";\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e+\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eimport { data } from \\\\\\\"@remix-run/node\\\\\\\";\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e// This example assumes you already have a headers function to handle header\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e// merging for your document requests\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003eexport function headers() {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e // ...\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003eexport async function loader({}: LoaderFunctionArgs) {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e let tasks = await fetchTasks();\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e-\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003e return json(tasks, {\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e+\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e return data(tasks, {\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e headers: {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e \\\\\\\"Cache-Control\\\\\\\": \\\\\\\"public, max-age=604800\\\\\\\"\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e }\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e });\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"18\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eAdjust your server abort delay\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eIf you were using a custom \\u003ccode\\u003eABORT_DELAY\\u003c/code\\u003e in your \\u003ccode\\u003eentry.server.tsx\\u003c/code\\u003e file, you should change that to use the new \\u003ccode\\u003estreamTimeout\\u003c/code\\u003e API leveraged by Single Fetch:\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"entry.server.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"diff\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"entry.server.tsx\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"diff\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e-\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003econst ABORT_DELAY = 5000;\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e+\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e// Reject/cancel all pending promises after 5 seconds\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e+\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eexport const streamTimeout = 5000;\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e// ...\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003efunction handleBrowserRequest(/* ... */) {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e return new Promise((resolve, reject) =\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e const { pipe, abort } = renderToPipeableStream(\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e \\u0026#x3C;RemixServer\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e context={remixContext}\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e url={request.url}\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e-\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003e abortDelay={ABORT_DELAY}\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e /\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e onShellReady() {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e /* ... */\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"18\\\\\\\"\\u003e },\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"19\\\\\\\"\\u003e onShellError(error: unknown) {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"20\\\\\\\"\\u003e /* ... */\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"21\\\\\\\"\\u003e },\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"22\\\\\\\"\\u003e onError(error: unknown) {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"23\\\\\\\"\\u003e /* ... */\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"24\\\\\\\"\\u003e },\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"25\\\\\\\"\\u003e }\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"26\\\\\\\"\\u003e );\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"27\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"28\\\\\\\"\\u003e-\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003e setTimeout(abort, ABORT_DELAY);\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"29\\\\\\\"\\u003e+\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e // Automatically timeout the React renderer after 6 seconds, which ensures\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"30\\\\\\\"\\u003e+\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e // React has enough time to flush down the rejected boundary contents\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"31\\\\\\\"\\u003e+\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e setTimeout(abort, streamTimeout + 1000);\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"32\\\\\\\"\\u003e });\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"33\\\\\\\"\\u003e}\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003ch2 id=\\\\\\\"v3_routeconfig\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#v3_routeconfig\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003ev3_routeConfig\\u003c/h2\\u003e\\\\n\\u003cdocs-warning\\u003e\\\\n\\u003cp\\u003eThis flag requires the \\u003ca href=\\\\\\\"#adopt-the-vite-plugin\\\\\\\"\\u003eVite plugin\\u003c/a\\u003e.\\u003c/p\\u003e\\\\n\\u003c/docs-warning\\u003e\\\\n\\u003cp\\u003eConfig-based routing is the new default in React Router v7, configured via the \\u003ccode\\u003eroutes.ts\\u003c/code\\u003e file in the app directory. Support for \\u003ccode\\u003eroutes.ts\\u003c/code\\u003e and its related APIs in Remix are designed as a migration path to help minimize the number of changes required when moving your Remix project over to React Router v7. While some new packages have been introduced within the \\u003ccode\\u003e@remix-run\\u003c/code\\u003e scope, these new packages only exist to keep the code in \\u003ccode\\u003eroutes.ts\\u003c/code\\u003e as similar as possible to the equivalent code for React Router v7.\\u003c/p\\u003e\\\\n\\u003cp\\u003eWhen the \\u003ccode\\u003ev3_routeConfig\\u003c/code\\u003e future flag is enabled, Remix's built-in file system routing will be disabled and your project will opt into React Router v7's config-based routing. If you prefer to keep using Remix's file-based routing, we cover how to enable it in \\u003ccode\\u003eroutes.ts\\u003c/code\\u003e below.\\u003c/p\\u003e\\\\n\\u003cp\\u003e\\u003cstrong\\u003eUpdate your code\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eTo migrate Remix's file system routing and route config to the equivalent setup in React Router v7, you can follow these steps:\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eEnable the Flag\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"vite.config.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"vite.config.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eremix\\u003c/span\\u003e({\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e future: {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e v3_routeConfig: \\u003cspan style=\\\\\\\"color: var(--base09)\\\\\\\"\\u003etrue\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e },\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e});\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eInstall \\u003ccode\\u003e@remix-run/route-config\\u003c/code\\u003e\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eThis package matches the API of React Router v7's \\u003ccode\\u003e@react-router/dev/routes\\u003c/code\\u003e, making the React Router v7 migration as easy as possible.\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\"\\u003e\\u003cpre data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003enpm\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003einstall\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e-D\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/route-config\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eThis provides the core \\u003ccode\\u003eRouteConfig\\u003c/code\\u003e type as well as a set of helpers for configuring routes in code.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eAdd an \\u003ccode\\u003eapp/routes.ts\\u003c/code\\u003e file without any configured routes\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\"\\u003e\\u003cpre data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003etouch\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eapp/routes.ts\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/routes.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/routes.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003etype\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eRouteConfig\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/route-config\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003edefault\\u003c/span\\u003e [] \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003esatisfies\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eRouteConfig\\u003c/span\\u003e;\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eThis is a good way to check that your new \\u003ccode\\u003eroutes.ts\\u003c/code\\u003e file is being picked up successfully. Your app should now be rendering a blank page since there aren't any routes defined yet.\\u003c/p\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eInstall \\u003ccode\\u003e@remix-run/fs-routes\\u003c/code\\u003e and use it in \\u003ccode\\u003eroutes.ts\\u003c/code\\u003e\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\"\\u003e\\u003cpre data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003enpm\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003einstall\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e-D\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/fs-routes\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eThis package matches the API of React Router v7's \\u003ccode\\u003e@react-router/fs-routes\\u003c/code\\u003e, making the React Router v7 migration as easy as possible.\\u003c/p\\u003e\\\\n\\u003cblockquote\\u003e\\\\n\\u003cp\\u003eIf you've configured \\u003ccode\\u003eignoredRouteFiles\\u003c/code\\u003e to \\u003ccode\\u003e[\\\\\\\"**/*\\\\\\\"]\\u003c/code\\u003e, you should skip this step since you're already opting out of Remix's file system routing.\\u003c/p\\u003e\\\\n\\u003c/blockquote\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/routes.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/routes.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eflatRoutes\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/fs-routes\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003edefault\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eflatRoutes\\u003c/span\\u003e();\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003e👉 \\u003cstrong\\u003eIf you used the \\u003ccode\\u003eroutes\\u003c/code\\u003e config option, add \\u003ccode\\u003e@remix-run/routes-option-adapter\\u003c/code\\u003e and use it in \\u003ccode\\u003eroutes.ts\\u003c/code\\u003e\\u003c/strong\\u003e\\u003c/p\\u003e\\\\n\\u003cp\\u003eRemix provides a mechanism for defining routes in code and plugging in alternative file system routing conventions, available via the \\u003ccode\\u003eroutes\\u003c/code\\u003e option on the Vite plugin.\\u003c/p\\u003e\\\\n\\u003cp\\u003eTo make migration easier, an adapter package is available that converts Remix's \\u003ccode\\u003eroutes\\u003c/code\\u003e option into React Router's \\u003ccode\\u003eRouteConfig\\u003c/code\\u003e array.\\u003c/p\\u003e\\\\n\\u003cp\\u003eTo get started, first install the adapter:\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\"\\u003e\\u003cpre data-nonumber=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"false\\\\\\\" data-lang=\\\\\\\"shellscript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003enpm\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003einstall\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e-D\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/routes-option-adapter\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eThis package matches the API of React Router v7's \\u003ccode\\u003e@react-router/remix-routes-option-adapter\\u003c/code\\u003e, making the React Router v7 migration as easy as possible.\\u003c/p\\u003e\\\\n\\u003cp\\u003eThen, update your \\u003ccode\\u003eroutes.ts\\u003c/code\\u003e file to use the adapter, passing the value of your \\u003ccode\\u003eroutes\\u003c/code\\u003e option to the \\u003ccode\\u003eremixRoutesOptionAdapter\\u003c/code\\u003e function which will return an array of configured routes.\\u003c/p\\u003e\\\\n\\u003cp\\u003eFor example, if you were using the \\u003ccode\\u003eroutes\\u003c/code\\u003e option to use an alternative file system routing implementation like \\u003ca href=\\\\\\\"https://github.com/kiliman/remix-flat-routes\\\\\\\"\\u003eremix-flat-routes\\u003c/a\\u003e:\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/routes.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/routes.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003etype\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eRouteConfig\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/route-config\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eremixRoutesOptionAdapter\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/routes-option-adapter\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eflatRoutes\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eremix-flat-routes\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003edefault\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eremixRoutesOptionAdapter\\u003c/span\\u003e((\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003edefineRoutes\\u003c/span\\u003e) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eflatRoutes\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eroutes\\u003c/span\\u003e\\\\\\\", \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003edefineRoutes\\u003c/span\\u003e)\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e) \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003esatisfies\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eRouteConfig\\u003c/span\\u003e;\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eOr, if you were using the \\u003ccode\\u003eroutes\\u003c/code\\u003e option to define config-based routes:\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-filename=\\\\\\\"app/routes.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\"\\u003e\\u003cpre data-filename=\\\\\\\"app/routes.ts\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eflatRoutes\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/fs-routes\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003etype\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eRouteConfig\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/route-config\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eremixRoutesOptionAdapter\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/routes-option-adapter\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003edefault\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eremixRoutesOptionAdapter\\u003c/span\\u003e((\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003edefineRoutes\\u003c/span\\u003e) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003edefineRoutes\\u003c/span\\u003e((\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eroute\\u003c/span\\u003e) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eroute\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e/\\u003c/span\\u003e\\\\\\\", \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003ehome/route.tsx\\u003c/span\\u003e\\\\\\\", { index: \\u003cspan style=\\\\\\\"color: var(--base09)\\\\\\\"\\u003etrue\\u003c/span\\u003e });\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eroute\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eabout\\u003c/span\\u003e\\\\\\\", \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eabout/route.tsx\\u003c/span\\u003e\\\\\\\");\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eroute\\u003c/span\\u003e(\\\\\\\"\\\\\\\", \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003econcerts/layout.tsx\\u003c/span\\u003e\\\\\\\", () \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eroute\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003etrending\\u003c/span\\u003e\\\\\\\", \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003econcerts/trending.tsx\\u003c/span\\u003e\\\\\\\");\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eroute\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e:city\\u003c/span\\u003e\\\\\\\", \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003econcerts/city.tsx\\u003c/span\\u003e\\\\\\\");\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e });\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e });\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e}) \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003esatisfies\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eRouteConfig\\u003c/span\\u003e;\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eIf you're defining config-based routes in this way, you might want to consider migrating to the new route config API since it's more streamlined while still being very similar to the old API. For example, the routes above would look like this:\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\"\\u003e\\u003cpre data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003etype\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eRouteConfig\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eroute\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003elayout\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eindex\\u003c/span\\u003e,\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e} \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/route-config\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003edefault\\u003c/span\\u003e [\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eindex\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003ehome/route.tsx\\u003c/span\\u003e\\\\\\\"),\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eroute\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eabout\\u003c/span\\u003e\\\\\\\", \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eabout/route.tsx\\u003c/span\\u003e\\\\\\\"),\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003elayout\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003econcerts/layout.tsx\\u003c/span\\u003e\\\\\\\", [\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eroute\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003etrending\\u003c/span\\u003e\\\\\\\", \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003econcerts/trending.tsx\\u003c/span\\u003e\\\\\\\"),\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eroute\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e:city\\u003c/span\\u003e\\\\\\\", \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003econcerts/city.tsx\\u003c/span\\u003e\\\\\\\"),\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"14\\\\\\\"\\u003e ]),\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"15\\\\\\\"\\u003e] \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003esatisfies\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eRouteConfig\\u003c/span\\u003e;\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eNote that if you need to mix and match different route config approaches, they can be merged into a single array of routes. The \\u003ccode\\u003eRouteConfig\\u003c/code\\u003e type ensures that everything is still valid.\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\"\\u003e\\u003cpre data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eflatRoutes\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/fs-routes\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"2\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003etype\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eRouteConfig\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/route-config\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"3\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eroute\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/route-config\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"4\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eremixRoutesOptionAdapter\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/routes-option-adapter\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"6\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003edefault\\u003c/span\\u003e [\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"7\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e...\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eawait\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eflatRoutes\\u003c/span\\u003e({ rootDirectory: \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003efs-routes\\u003c/span\\u003e\\\\\\\" })),\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"9\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e...\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eawait\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eremixRoutesOptionAdapter\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e/* ... */\\u003c/span\\u003e)),\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"10\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eroute\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e/hello\\u003c/span\\u003e\\\\\\\", \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003eroutes/hello.tsx\\u003c/span\\u003e\\\\\\\"),\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e] \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003esatisfies\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eRouteConfig\\u003c/span\\u003e;\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003ch2 id=\\\\\\\"deprecations\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#deprecations\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eDeprecations\\u003c/h2\\u003e\\\\n\\u003ch3 id=\\\\\\\"remix-runeslint-config\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#remix-runeslint-config\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003e@remix-run/eslint-config\\u003c/h3\\u003e\\\\n\\u003cp\\u003eThe \\u003ccode\\u003e@remix-run/eslint-config\\u003c/code\\u003e package is deprecated and will not be included in React Router v7. We recommend moving towards a streamlined ESLint config such as the ones included in \\u003ca href=\\\\\\\"https://github.com/remix-run/remix/blob/main/templates/remix/.eslintrc.cjs\\\\\\\"\\u003ethe Remix templates\\u003c/a\\u003e.\\u003c/p\\u003e\\\\n\\u003ch3 id=\\\\\\\"json\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#json\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003ejson\\u003c/h3\\u003e\\\\n\\u003cp\\u003eThis utility is deprecated and will be removed in React Router v7 in favor of \\u003ca href=\\\\\\\"#v3_singlefetch\\\\\\\"\\u003eSingle Fetch\\u003c/a\\u003e naked object returns.\\u003c/p\\u003e\\\\n\\u003cul\\u003e\\\\n\\u003cli\\u003eIf you were not relying on \\u003ccode\\u003ejson\\u003c/code\\u003e to serialize your data (such as stringifying \\u003ccode\\u003eDate\\u003c/code\\u003e objects), you can safely remove it.\\u003c/li\\u003e\\\\n\\u003cli\\u003eIf you were returning \\u003ccode\\u003eheaders\\u003c/code\\u003e or \\u003ccode\\u003estatus\\u003c/code\\u003e via \\u003ccode\\u003ejson\\u003c/code\\u003e, you can use the new \\u003ca href=\\\\\\\"../utils/data\\\\\\\"\\u003edata util\\u003c/a\\u003e as a drop-in replacement to set those values.\\u003c/li\\u003e\\\\n\\u003cli\\u003eIf you want to serialize your data to JSON, you can use the native \\u003ca href=\\\\\\\"https://developer.mozilla.org/en-US/docs/Web/API/Response/json\\\\\\\"\\u003eResponse.json()\\u003c/a\\u003e method.\\u003c/li\\u003e\\\\n\\u003c/ul\\u003e\\\\n\\u003cp\\u003eView the \\u003ca href=\\\\\\\"#v3_singlefetch\\\\\\\"\\u003eSingle Fetch\\u003c/a\\u003e docs for more information.\\u003c/p\\u003e\\\\n\\u003ch3 id=\\\\\\\"defer\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#defer\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003edefer\\u003c/h3\\u003e\\\\n\\u003cp\\u003eThis utility is deprecated and will be removed in React Router v7 in favor of \\u003ca href=\\\\\\\"#v3_singlefetch\\\\\\\"\\u003eSingle Fetch\\u003c/a\\u003e naked object returns.\\u003c/p\\u003e\\\\n\\u003cul\\u003e\\\\n\\u003cli\\u003eIf you were returning \\u003ccode\\u003eheaders\\u003c/code\\u003e or \\u003ccode\\u003estatus\\u003c/code\\u003e via \\u003ccode\\u003edefer\\u003c/code\\u003e, you can use the new \\u003ca href=\\\\\\\"../utils/data\\\\\\\"\\u003edata util\\u003c/a\\u003e as a drop-in replacement to set those values.\\u003c/li\\u003e\\\\n\\u003c/ul\\u003e\\\\n\\u003cp\\u003eView the \\u003ca href=\\\\\\\"#v3_singlefetch\\\\\\\"\\u003eSingle Fetch\\u003c/a\\u003e docs for more information.\\u003c/p\\u003e\\\\n\\u003ch3 id=\\\\\\\"serializefrom\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#serializefrom\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eSerializeFrom\\u003c/h3\\u003e\\\\n\\u003cp\\u003eThis type is deprecated and will be removed in React Router v7 since \\u003ca href=\\\\\\\"#v3_singlefetch\\\\\\\"\\u003eSingle Fetch\\u003c/a\\u003e no longer serializes data to JSON.\\u003c/p\\u003e\\\\n\\u003cp\\u003eIf you are relying on \\u003ccode\\u003eSerializeFrom\\u003c/code\\u003e to unwrap your \\u003ccode\\u003eloader\\u003c/code\\u003e/\\u003ccode\\u003eaction\\u003c/code\\u003e data, you can use a custom type like this:\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\"\\u003e\\u003cpre data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"typescript\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003etype\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eSerializeFrom\\u003c/span\\u003e\\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eT\\u003c/span\\u003e\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eReturnType\\u003c/span\\u003e\\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003etypeof\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003euseLoaderData\\u003c/span\\u003e\\u0026#x3C;\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003eT\\u003c/span\\u003e\\u003e\\u003e;\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eIn most cases, you should be able to just remove \\u003ccode\\u003eSerializeFrom\\u003c/code\\u003e and use the types returned from \\u003ccode\\u003euseLoaderData\\u003c/code\\u003e/\\u003ccode\\u003euseActionData\\u003c/code\\u003e, or the types of the data in \\u003ccode\\u003eloader\\u003c/code\\u003e/\\u003ccode\\u003eaction\\u003c/code\\u003e functions.\\u003c/p\\u003e\\\\n\\u003ch3 id=\\\\\\\"multipart-form-data-and-file-upload-utilities\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#multipart-form-data-and-file-upload-utilities\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eMultipart Form Data and File Upload utilities\\u003c/h3\\u003e\\\\n\\u003cp\\u003eThe following utilities are deprecated and will be removed in React Router v7:\\u003c/p\\u003e\\\\n\\u003cul\\u003e\\\\n\\u003cli\\u003e\\u003ccode\\u003eunstable_parseMultipartFormData\\u003c/code\\u003e\\u003c/li\\u003e\\\\n\\u003cli\\u003e\\u003ccode\\u003eunstable_composeUploadHandlers\\u003c/code\\u003e\\u003c/li\\u003e\\\\n\\u003cli\\u003e\\u003ccode\\u003eunstable_createFileUploadHandler\\u003c/code\\u003e\\u003c/li\\u003e\\\\n\\u003cli\\u003e\\u003ccode\\u003eunstable_createMemoryUploadHandler\\u003c/code\\u003e\\u003c/li\\u003e\\\\n\\u003c/ul\\u003e\\\\n\\u003cp\\u003eWe recommend using \\u003ca href=\\\\\\\"https://github.com/mjackson/remix-the-web/tree/main/packages/form-data-parser\\\\\\\"\\u003e\\u003ccode\\u003e@mjackson/form-data-parser\\u003c/code\\u003e\\u003c/a\\u003e and \\u003ca href=\\\\\\\"https://github.com/mjackson/remix-the-web/tree/main/packages/file-storage\\\\\\\"\\u003e\\u003ccode\\u003e@mjackson/file-storage\\u003c/code\\u003e\\u003c/a\\u003e to handle multipart form data and file uploads.\\u003c/p\\u003e\\\\n\\u003cp\\u003eYou can also check out the \\u003ca href=\\\\\\\"https://reactrouter.com/how-to/file-uploads\\\\\\\"\\u003eReact Router \\\\\\\"File Uploads\\\\\\\" doc\\u003c/a\\u003e or \\u003ca href=\\\\\\\"https://programmingarehard.com/2024/09/06/remix-file-uploads-updated.html/\\\\\\\"\\u003e\\\\\\\"File uploads with Remix\\\\\\\"\\u003c/a\\u003e blog post for guides on using these libraries.\\u003c/p\\u003e\\\",\\\"docs/start/future-flags\\\",\\\"headings\\\",[960,965,968,971,974,977,980,983,986,989,992,996,997,998,1001],{\\\"_961\\\":962,\\\"_955\\\":963,\\\"_24\\\":964},\\\"headingLevel\\\",\\\"h2\\\",\\\"Update to latest v2.x\\\",\\\"update-to-latest-v2x\\\",{\\\"_961\\\":962,\\\"_955\\\":966,\\\"_24\\\":967},\\\"Remove \\u003ccode\\u003einstallGlobals\\u003c/code\\u003e\\\",\\\"remove-installglobals\\\",{\\\"_961\\\":962,\\\"_955\\\":969,\\\"_24\\\":970},\\\"Adopt the Vite Plugin\\\",\\\"adopt-the-vite-plugin\\\",{\\\"_961\\\":962,\\\"_955\\\":972,\\\"_24\\\":973},\\\"v3_fetcherPersist\\\",\\\"v3_fetcherpersist\\\",{\\\"_961\\\":962,\\\"_955\\\":975,\\\"_24\\\":976},\\\"v3_relativeSplatPath\\\",\\\"v3_relativesplatpath\\\",{\\\"_961\\\":962,\\\"_955\\\":978,\\\"_24\\\":979},\\\"v3_throwAbortReason\\\",\\\"v3_throwabortreason\\\",{\\\"_961\\\":962,\\\"_955\\\":981,\\\"_24\\\":982},\\\"v3_lazyRouteDiscovery\\\",\\\"v3_lazyroutediscovery\\\",{\\\"_961\\\":962,\\\"_955\\\":984,\\\"_24\\\":985},\\\"v3_singleFetch\\\",\\\"v3_singlefetch\\\",{\\\"_961\\\":962,\\\"_955\\\":987,\\\"_24\\\":988},\\\"v3_routeConfig\\\",\\\"v3_routeconfig\\\",{\\\"_961\\\":962,\\\"_955\\\":990,\\\"_24\\\":991},\\\"Deprecations\\\",\\\"deprecations\\\",{\\\"_961\\\":993,\\\"_955\\\":994,\\\"_24\\\":995},\\\"h3\\\",\\\"@remix-run/eslint-config\\\",\\\"remix-runeslint-config\\\",{\\\"_961\\\":993,\\\"_955\\\":565,\\\"_24\\\":565},{\\\"_961\\\":993,\\\"_955\\\":553,\\\"_24\\\":553},{\\\"_961\\\":993,\\\"_955\\\":999,\\\"_24\\\":1000},\\\"SerializeFrom\\\",\\\"serializefrom\\\",{\\\"_961\\\":993,\\\"_955\\\":1002,\\\"_24\\\":1003},\\\"Multipart Form Data and File Upload utilities\\\",\\\"multipart-form-data-and-file-upload-utilities\\\",[],\\\"actionData\\\",\\\"errors\\\"]\\n\");function $RC(a,b){a=document.getElementById(a);b=document.getElementById(b);b.parentNode.removeChild(b);if(a){a=a.previousSibling;var f=a.parentNode,c=a.nextSibling,e=0;do{if(c\u0026\u00268===c.nodeType){var d=c.data;if(\"/$\"===d)if(0===e)break;else e--;else\"$\"!==d\u0026\u0026\"$?\"!==d\u0026\u0026\"$!\"!==d||e++}d=c.nextSibling;f.removeChild(c);c=d}while(c);for(;b.firstChild;)f.insertBefore(b.firstChild,c);a.data=\"$\";a._reactRetry\u0026\u0026a._reactRetry()}};$RC(\"B:0\",\"S:0\")window.__reactRouterContext.streamController.close();$RC(\"B:1\",\"S:1\")",
|
|
"url": "https://v2.remix.run/docs/start/future-flags",
|
|
"metadata": {
|
|
"description": "",
|
|
"headings": [
|
|
"Future Flags and Deprecations",
|
|
"Update to latest v2.x",
|
|
"Remove installGlobals",
|
|
"Adopt the Vite Plugin",
|
|
"v3_fetcherPersist",
|
|
"v3_relativeSplatPath",
|
|
"v3_throwAbortReason",
|
|
"v3_lazyRouteDiscovery",
|
|
"v3_singleFetch",
|
|
"v3_routeConfig",
|
|
"Deprecations",
|
|
"@remix-run/eslint-config",
|
|
"json",
|
|
"defer",
|
|
"SerializeFrom",
|
|
"Multipart Form Data and File Upload utilities"
|
|
],
|
|
"images": [
|
|
"/assets/icons-CZ8v8NWl.svg"
|
|
],
|
|
"links": [
|
|
"/",
|
|
"/docs",
|
|
"https://remix.run/blog",
|
|
"/resources",
|
|
"https://reactrouter.com/home",
|
|
"https://github.com/remix-run/remix/tree/v2",
|
|
"https://rmx.as/discord",
|
|
"/docs/start/quickstart",
|
|
"/docs/start/tutorial",
|
|
"/docs/start/v2",
|
|
"/docs/start/community",
|
|
"/docs/start/future-flags",
|
|
"/docs/start/changelog",
|
|
"/docs/discussion/introduction",
|
|
"/docs/discussion/runtimes",
|
|
"/docs/discussion/routes",
|
|
"/docs/discussion/data-flow",
|
|
"/docs/discussion/server-vs-client",
|
|
"/docs/discussion/react-router",
|
|
"/docs/discussion/progressive-enhancement",
|
|
"/docs/discussion/pending-ui",
|
|
"/docs/discussion/state-management",
|
|
"/docs/discussion/concurrency",
|
|
"/docs/discussion/form-vs-fetcher",
|
|
"/docs/discussion/hot-module-replacement",
|
|
"/docs/discussion/resubmissions",
|
|
"/docs/file-conventions/-client",
|
|
"/docs/file-conventions/-server",
|
|
"/docs/file-conventions/asset-imports",
|
|
"/docs/file-conventions/entry.client",
|
|
"/docs/file-conventions/entry.server",
|
|
"/docs/file-conventions/root",
|
|
"/docs/file-conventions/routes",
|
|
"/docs/file-conventions/vite-config",
|
|
"/docs/route/action",
|
|
"/docs/route/client-action",
|
|
"/docs/route/client-loader",
|
|
"/docs/route/component",
|
|
"/docs/route/error-boundary",
|
|
"/docs/route/handle",
|
|
"/docs/route/headers",
|
|
"/docs/route/hydrate-fallback",
|
|
"/docs/route/links",
|
|
"/docs/route/loader",
|
|
"/docs/route/meta",
|
|
"/docs/route/should-revalidate",
|
|
"/docs/components/await",
|
|
"/docs/components/form",
|
|
"/docs/components/link",
|
|
"/docs/components/links",
|
|
"/docs/components/live-reload",
|
|
"/docs/components/meta",
|
|
"/docs/components/nav-link",
|
|
"/docs/components/outlet",
|
|
"/docs/components/prefetch-page-links",
|
|
"/docs/components/scripts",
|
|
"/docs/components/scroll-restoration",
|
|
"/docs/hooks/use-action-data",
|
|
"/docs/hooks/use-async-error",
|
|
"/docs/hooks/use-async-value",
|
|
"/docs/hooks/use-before-unload",
|
|
"/docs/hooks/use-blocker",
|
|
"/docs/hooks/use-fetcher",
|
|
"/docs/hooks/use-fetchers",
|
|
"/docs/hooks/use-form-action",
|
|
"/docs/hooks/use-href",
|
|
"/docs/hooks/use-loader-data",
|
|
"/docs/hooks/use-location",
|
|
"/docs/hooks/use-matches",
|
|
"/docs/hooks/use-navigate",
|
|
"/docs/hooks/use-navigation",
|
|
"/docs/hooks/use-navigation-type",
|
|
"/docs/hooks/use-outlet",
|
|
"/docs/hooks/use-outlet-context",
|
|
"/docs/hooks/use-params",
|
|
"/docs/hooks/use-prompt",
|
|
"/docs/hooks/use-resolved-path",
|
|
"/docs/hooks/use-revalidator",
|
|
"/docs/hooks/use-route-error",
|
|
"/docs/hooks/use-route-loader-data",
|
|
"/docs/hooks/use-search-params",
|
|
"/docs/hooks/use-submit",
|
|
"/docs/hooks/use-view-transition-state",
|
|
"/docs/utils/cookies",
|
|
"/docs/utils/create-remix-stub",
|
|
"/docs/utils/data",
|
|
"/docs/utils/defer",
|
|
"/docs/utils/is-route-error-response",
|
|
"/docs/utils/json",
|
|
"/docs/utils/parse-multipart-form-data",
|
|
"/docs/utils/redirect",
|
|
"/docs/utils/redirectDocument",
|
|
"/docs/utils/replace",
|
|
"/docs/utils/sessions",
|
|
"/docs/utils/unstable-create-file-upload-handler",
|
|
"/docs/utils/unstable-create-memory-upload-handler",
|
|
"/docs/styling/bundling",
|
|
"/docs/styling/css",
|
|
"/docs/styling/css-imports",
|
|
"/docs/styling/css-in-js",
|
|
"/docs/styling/css-modules",
|
|
"/docs/styling/postcss",
|
|
"/docs/styling/tailwind",
|
|
"/docs/styling/vanilla-extract",
|
|
"/docs/other-api/dev",
|
|
"/docs/other-api/adapter",
|
|
"/docs/other-api/serve",
|
|
"/docs/other-api/create-remix",
|
|
"/docs/other-api/node",
|
|
"/docs/other-api/testing",
|
|
"/docs/guides/accessibility",
|
|
"/docs/guides/api-development-strategy",
|
|
"/docs/guides/api-routes",
|
|
"/docs/guides/bff",
|
|
"/docs/guides/breadcrumbs",
|
|
"/docs/guides/browser-support",
|
|
"/docs/guides/client-data",
|
|
"/docs/guides/constraints",
|
|
"/docs/guides/contributing",
|
|
"/docs/guides/css-files",
|
|
"/docs/guides/data-loading",
|
|
"/docs/guides/data-writes",
|
|
"/docs/guides/dependency-optimization",
|
|
"/docs/guides/deployment",
|
|
"/docs/guides/disabling-javascript",
|
|
"/docs/guides/envvars",
|
|
"/docs/guides/errors",
|
|
"/docs/guides/faq",
|
|
"/docs/guides/file-uploads",
|
|
"/docs/guides/form-validation",
|
|
"/docs/guides/gotchas",
|
|
"/docs/guides/index-query-param",
|
|
"/docs/guides/lazy-route-discovery",
|
|
"/docs/guides/local-tls",
|
|
"/docs/guides/manual-mode",
|
|
"/docs/guides/mdx",
|
|
"/docs/guides/migrating-react-router-app",
|
|
"/docs/guides/not-found",
|
|
"/docs/guides/performance",
|
|
"/docs/guides/presets",
|
|
"/docs/guides/resource-routes",
|
|
"/docs/guides/server-bundles",
|
|
"/docs/guides/single-fetch",
|
|
"/docs/guides/spa-mode",
|
|
"/docs/guides/streaming",
|
|
"/docs/guides/templates",
|
|
"/docs/guides/typescript",
|
|
"/docs/guides/vite",
|
|
"/docs/start/future-flags/#update-to-latest-v2x",
|
|
"/docs/start/future-flags/#remove-installglobals",
|
|
"/docs/start/future-flags/#adopt-the-vite-plugin",
|
|
"/docs/start/future-flags/#v3_fetcherpersist",
|
|
"/docs/start/future-flags/#v3_relativesplatpath",
|
|
"/docs/start/future-flags/#v3_throwabortreason",
|
|
"/docs/start/future-flags/#v3_lazyroutediscovery",
|
|
"/docs/start/future-flags/#v3_singlefetch",
|
|
"/docs/start/future-flags/#v3_routeconfig",
|
|
"/docs/start/future-flags/#deprecations",
|
|
"/docs/start/future-flags/#remix-runeslint-config",
|
|
"/docs/start/future-flags/#json",
|
|
"/docs/start/future-flags/#defer",
|
|
"/docs/start/future-flags/#serializefrom",
|
|
"/docs/start/future-flags/#multipart-form-data-and-file-upload-utilities",
|
|
"../guides/api-development-strategy",
|
|
"https://developers.cloudflare.com/workers/configuration/compatibility-dates",
|
|
"https://vitejs.dev",
|
|
"../guides/vite",
|
|
"../file-conventions/vite-config",
|
|
"../guides/dependency-optimization",
|
|
"https://github.com/aleclarson/vite-tsconfig-paths",
|
|
"../styling/bundling",
|
|
"../styling/css",
|
|
"https://vitejs.dev/guide/assets.html#explicit-url-imports",
|
|
"../guides/vite#enable-tailwind-via-postcss",
|
|
"../guides/vite#migrating-a-custom-server",
|
|
"https://mdxjs.com",
|
|
"https://mdxjs.com/packages/rollup",
|
|
"../guides/vite#add-mdx-plugin",
|
|
"https://github.com/remix-run/remix/discussions/7698",
|
|
"https://github.com/remix-run/remix/blob/v2/CHANGELOG.md#futurev3_relativesplatpath",
|
|
"../guides/lazy-route-discovery",
|
|
"https://remix.run/blog/fog-of-war",
|
|
"../components/link#discover",
|
|
"../guides/single-fetch",
|
|
"https://github.com/kiliman/remix-flat-routes",
|
|
"https://github.com/remix-run/remix/blob/main/templates/remix/.eslintrc.cjs",
|
|
"../utils/data",
|
|
"https://developer.mozilla.org/en-US/docs/Web/API/Response/json",
|
|
"https://github.com/mjackson/remix-the-web/tree/main/packages/form-data-parser",
|
|
"https://github.com/mjackson/remix-the-web/tree/main/packages/file-storage",
|
|
"https://reactrouter.com/how-to/file-uploads",
|
|
"https://programmingarehard.com/2024/09/06/remix-file-uploads-updated.html/",
|
|
"https://remix.run",
|
|
"https://opensource.org/licenses/MIT",
|
|
"https://github.com/remix-run/remix-v2-website/edit/main/data/docs/start/future-flags.md"
|
|
]
|
|
},
|
|
"hash": "532b8f1030f84e8ac3d082a0ef28481266a0a529bcfb577069e0d3a627cb2583",
|
|
"timestamp": "2026-02-23T11:36:17.735261359+01:00"
|
|
} |