mirror of
https://github.com/Dvorinka/Devour.git
synced 2026-06-04 04:23:02 +00:00
187 lines
65 KiB
JSON
187 lines
65 KiB
JSON
{
|
|
"id": "2073b024dbb146b3dc377d6b",
|
|
"source": "remix:does",
|
|
"type": "html",
|
|
"title": "Runtimes, Adapters, Templates, and Deployment | Remix",
|
|
"content": "DocsBlogResourcesReact Router v7 has been released. View the docsDocsBlogResourcesView code on GitHubChat on DiscordReact Router v7 has been released. View the docsRuntimes, Adapters, Templates, and DeploymentGetting 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 pageJavaScript RuntimesAdaptersRemix App ServerTemplatesOn this pageJavaScript RuntimesAdaptersRemix App ServerTemplatesRuntimes, Adapters, Templates, and Deployment Deploying a Remix application has four layers: A JavaScript Runtime like Node.js A JavaScript web server like Express.js A server adapter like @remix-run/express A web host or platform Depending on your web host, you may have fewer layers. For example, deploying to Cloudflare Pages takes care of 2, 3, and 4 all at once. Deploying Remix inside an Express app will have all four, and using the \"Remix App Server\" combines 2 and 3! You can wire all of these up yourself or start with a Remix Template. Let's talk about what each part does. JavaScript Runtimes Remix can be deployed to any JavaScript runtime like Node.js, Shopify Oxygen, Cloudflare Workers/Pages, Fastly Compute, Deno, Bun, etc. Each runtime has varying support for the standard Web APIs that Remix is built on, so a Remix runtime package is required to polyfill any missing features of the runtime. These polyfills include web standard APIs like Request, Response, crypto, and more. This allows you to use the same APIs on the server as in the browser. The following runtimes packages are available: @remix-run/cloudflare-pages @remix-run/cloudflare-workers @remix-run/deno @remix-run/node The majority of the APIs you interact with in your app are not imported directly from these packages, so your code is fairly portable between runtimes. However, occasionally you'll import something from these packages for a specific feature that isn't a standard Web API. For example, you might want to store cookies on the file system or in Cloudflare KV storage. These are specific features of runtimes that aren't shared with other runtimes: // store sessions in cloudflare KV storage import { createWorkersKVSessionStorage } from \"@remix-run/cloudflare\"; // store sessions on the file system in node import { createFileSessionStorage } from \"@remix-run/node\"; But if you're storing a session in the cookie itself, this is supported in all runtimes: import { createCookieSessionStorage } from \"@remix-run/node\"; // or cloudflare/deno Adapters Remix is not an HTTP server but rather a handler inside an existing HTTP server. Adapters allow the Remix handler to run inside the HTTP server. Some JavaScript runtimes, especially Node.js, have multiple ways to create an HTTP server. For example, in Node.js you can use Express.js, fastify, or raw http.createServer. Each of these servers has its own Request/Response API. The adapter's job is to convert the incoming request to a Web Fetch Request, run the Remix handler, and then adapt the Web Fetch Response back to the host server's response API. Here's some pseudocode that illustrates the flow. // import the app build created by `remix build` import build from \"./build/index.js\"; // an express http server const app = express(); // and here your Remix app is \"just a request handler\" app.all(\"*\", createRequestHandler({ build })); // This is pseudo code, but illustrates what adapters do: export function createRequestHandler({ build }) { // creates a Fetch API request handler from the server build const handleRequest = createRemixRequestHandler(build); // returns an express.js specific handler for the express server return async (req, res) =\u003e { // adapts the express.req to a Fetch API request const request = createRemixRequest(req); // calls the app handler and receives a Fetch API response const response = await handleRequest(request); // adapts the Fetch API response to the express.res sendRemixResponse(res, response); }; } Remix App Server For convenience, the Remix App Server is a basic express server for new projects, tinkering, or projects that don't have any specific needs from a server like Express and are deployed to Node.js environments. See @remix-run/serve Templates Remix is designed to be incredibly flexible with just enough opinions to connect the UI to the back end. However, it doesn't bring opinions on the database you use, how you cache data, or where and how your app is deployed. Remix templates are starting points for app development with all of these extra opinions baked in, created by the community. You can use a template with the --template flag in the Remix CLI that points to a repository on GitHub: npx create-remix@latest --template \u003corg\u003e/\u003crepo\u003e You can read more about templates in the Templates Guide. Once you've picked a template or set up an app from scratch, you're ready to start building your app!© 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,\\\"_975\\\":-5,\\\"_976\\\":-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\\\":974},{\\\"_18\\\":86,\\\"_20\\\":39},\\\"docs/discussion/runtimes.md\\\",\\\"html\\\",\\\"\\u003ch1 id=\\\\\\\"runtimes-adapters-templates-and-deployment\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#runtimes-adapters-templates-and-deployment\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eRuntimes, Adapters, Templates, and Deployment\\u003c/h1\\u003e\\\\n\\u003cp\\u003eDeploying a Remix application has four layers:\\u003c/p\\u003e\\\\n\\u003col\\u003e\\\\n\\u003cli\\u003eA JavaScript Runtime like Node.js\\u003c/li\\u003e\\\\n\\u003cli\\u003eA JavaScript web server like Express.js\\u003c/li\\u003e\\\\n\\u003cli\\u003eA server adapter like \\u003ccode\\u003e@remix-run/express\\u003c/code\\u003e\\u003c/li\\u003e\\\\n\\u003cli\\u003eA web host or platform\\u003c/li\\u003e\\\\n\\u003c/ol\\u003e\\\\n\\u003cp\\u003eDepending on your web host, you may have fewer layers. For example, deploying to Cloudflare Pages takes care of 2, 3, and 4 all at once. Deploying Remix inside an Express app will have all four, and using the \\\\\\\"Remix App Server\\\\\\\" combines 2 and 3!\\u003c/p\\u003e\\\\n\\u003cp\\u003eYou can wire all of these up yourself or start with a Remix Template.\\u003c/p\\u003e\\\\n\\u003cp\\u003eLet's talk about what each part does.\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"javascript-runtimes\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#javascript-runtimes\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eJavaScript Runtimes\\u003c/h2\\u003e\\\\n\\u003cp\\u003eRemix can be deployed to any JavaScript runtime like Node.js, Shopify Oxygen, Cloudflare Workers/Pages, Fastly Compute, Deno, Bun, etc.\\u003c/p\\u003e\\\\n\\u003cp\\u003eEach runtime has varying support for the standard Web APIs that Remix is built on, so a Remix runtime package is required to polyfill any missing features of the runtime. These polyfills include web standard APIs like Request, Response, crypto, and more. This allows you to use the same APIs on the server as in the browser.\\u003c/p\\u003e\\\\n\\u003cp\\u003eThe following runtimes packages are available:\\u003c/p\\u003e\\\\n\\u003cul\\u003e\\\\n\\u003cli\\u003e\\u003ca href=\\\\\\\"https://npm.im/@remix-run/cloudflare-pages\\\\\\\"\\u003e\\u003ccode\\u003e@remix-run/cloudflare-pages\\u003c/code\\u003e\\u003c/a\\u003e\\u003c/li\\u003e\\\\n\\u003cli\\u003e\\u003ca href=\\\\\\\"https://npm.im/@remix-run/cloudflare-workers\\\\\\\"\\u003e\\u003ccode\\u003e@remix-run/cloudflare-workers\\u003c/code\\u003e\\u003c/a\\u003e\\u003c/li\\u003e\\\\n\\u003cli\\u003e\\u003ca href=\\\\\\\"https://npm.im/@remix-run/deno\\\\\\\"\\u003e\\u003ccode\\u003e@remix-run/deno\\u003c/code\\u003e\\u003c/a\\u003e\\u003c/li\\u003e\\\\n\\u003cli\\u003e\\u003ca href=\\\\\\\"https://npm.im/@remix-run/node\\\\\\\"\\u003e\\u003ccode\\u003e@remix-run/node\\u003c/code\\u003e\\u003c/a\\u003e\\u003c/li\\u003e\\\\n\\u003c/ul\\u003e\\\\n\\u003cp\\u003eThe majority of the APIs you interact with in your app are not imported directly from these packages, so your code is fairly portable between runtimes. However, occasionally you'll import something from these packages for a specific feature that isn't a standard Web API.\\u003c/p\\u003e\\\\n\\u003cp\\u003eFor example, you might want to store cookies on the file system or in Cloudflare KV storage. These are specific features of runtimes that aren't shared with other runtimes:\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// store sessions in cloudflare KV storage\\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)\\\\\\\"\\u003ecreateWorkersKVSessionStorage\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/cloudflare\\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(--base03)\\\\\\\"\\u003e// store sessions on the file system in node\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eimport\\u003c/span\\u003e { \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ecreateFileSessionStorage\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/node\\u003c/span\\u003e\\\\\\\";\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003cp\\u003eBut if you're storing a session in the cookie itself, this is supported in all runtimes:\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\" 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)\\\\\\\"\\u003ecreateCookieSessionStorage\\u003c/span\\u003e } \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e@remix-run/node\\u003c/span\\u003e\\\\\\\"; \\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// or cloudflare/deno\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003ch2 id=\\\\\\\"adapters\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#adapters\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eAdapters\\u003c/h2\\u003e\\\\n\\u003cp\\u003eRemix is not an HTTP server but rather a handler inside an existing HTTP server. Adapters allow the Remix handler to run inside the HTTP server. Some JavaScript runtimes, especially Node.js, have multiple ways to create an HTTP server. For example, in Node.js you can use Express.js, fastify, or raw \\u003ccode\\u003ehttp.createServer\\u003c/code\\u003e.\\u003c/p\\u003e\\\\n\\u003cp\\u003eEach of these servers has its own Request/Response API. The adapter's job is to convert the incoming request to a Web Fetch Request, run the Remix handler, and then adapt the Web Fetch Response back to the host server's response API.\\u003c/p\\u003e\\\\n\\u003cp\\u003eHere's some pseudocode that illustrates the flow.\\u003c/p\\u003e\\\\n\\u003cdiv data-code-block=\\\\\\\"\\\\\\\" data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\"\\u003e\\u003cpre data-line-numbers=\\\\\\\"true\\\\\\\" data-lang=\\\\\\\"tsx\\\\\\\" style=\\\\\\\"color: var(--base05);\\\\\\\"\\u003e\\u003ccode\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"1\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// import the app build created by `remix build`\\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)\\\\\\\"\\u003ebuild\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003efrom\\u003c/span\\u003e \\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e./build/index.js\\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(--base03)\\\\\\\"\\u003e// an express http server\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"5\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eapp\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eexpress\\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\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// and here your Remix app is \\\\\\\"just a request handler\\\\\\\"\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"8\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eapp\\u003c/span\\u003e.\\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003eall\\u003c/span\\u003e(\\\\\\\"\\u003cspan style=\\\\\\\"color: var(--base0B)\\\\\\\"\\u003e*\\u003c/span\\u003e\\\\\\\", \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ecreateRequestHandler\\u003c/span\\u003e({ \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebuild\\u003c/span\\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\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// This is pseudo code, but illustrates what adapters do:\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"11\\\\\\\"\\u003e\\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eexport\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003efunction\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ecreateRequestHandler\\u003c/span\\u003e({ \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebuild\\u003c/span\\u003e }) {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"12\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// creates a Fetch API request handler from the server build\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"13\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ehandleRequest\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ecreateRemixRequestHandler\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ebuild\\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(--base03)\\\\\\\"\\u003e// returns an express.js specific handler for the express server\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"16\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003ereturn\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003easync\\u003c/span\\u003e (\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ereq\\u003c/span\\u003e, \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eres\\u003c/span\\u003e) \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003e=\\u003e\\u003c/span\\u003e {\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"17\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// adapts the express.req to a Fetch API request\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"18\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003erequest\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ecreateRemixRequest\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003ereq\\u003c/span\\u003e);\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"19\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"20\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// calls the app handler and receives a Fetch API response\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"21\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0A)\\\\\\\"\\u003econst\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eresponse\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003e=\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0E)\\\\\\\"\\u003eawait\\u003c/span\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003ehandleRequest\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003erequest\\u003c/span\\u003e);\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"22\\\\\\\"\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"23\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base03)\\\\\\\"\\u003e// adapts the Fetch API response to the express.res\\u003c/span\\u003e\\\\n\\u003c/span\\u003e\\u003cspan class=\\\\\\\"codeblock-line\\\\\\\" data-line-number=\\\\\\\"24\\\\\\\"\\u003e \\u003cspan style=\\\\\\\"color: var(--base0D)\\\\\\\"\\u003esendRemixResponse\\u003c/span\\u003e(\\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eres\\u003c/span\\u003e, \\u003cspan style=\\\\\\\"color: var(--base08)\\\\\\\"\\u003eresponse\\u003c/span\\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\\u003c/code\\u003e\\u003c/pre\\u003e\\u003c/div\\u003e\\\\n\\u003ch3 id=\\\\\\\"remix-app-server\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#remix-app-server\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eRemix App Server\\u003c/h3\\u003e\\\\n\\u003cp\\u003eFor convenience, the Remix App Server is a basic express server for new projects, tinkering, or projects that don't have any specific needs from a server like Express and are deployed to Node.js environments.\\u003c/p\\u003e\\\\n\\u003cp\\u003eSee \\u003ca href=\\\\\\\"../other-api/serve\\\\\\\"\\u003e\\u003ccode\\u003e@remix-run/serve\\u003c/code\\u003e\\u003c/a\\u003e\\u003c/p\\u003e\\\\n\\u003ch2 id=\\\\\\\"templates\\\\\\\"\\u003e\\u003ca aria-hidden=\\\\\\\"true\\\\\\\" tabindex=\\\\\\\"-1\\\\\\\" href=\\\\\\\"#templates\\\\\\\"\\u003e\\u003cspan class=\\\\\\\"icon icon-link\\\\\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003eTemplates\\u003c/h2\\u003e\\\\n\\u003cp\\u003eRemix is designed to be incredibly flexible with just enough opinions to connect the UI to the back end. However, it doesn't bring opinions on the database you use, how you cache data, or where and how your app is deployed.\\u003c/p\\u003e\\\\n\\u003cp\\u003eRemix templates are starting points for app development with all of these extra opinions baked in, created by the community.\\u003c/p\\u003e\\\\n\\u003cp\\u003eYou can use a template with the \\u003ccode\\u003e--template\\u003c/code\\u003e flag in the Remix CLI that points to a repository on GitHub:\\u003c/p\\u003e\\\\n\\u003cpre\\u003e\\u003ccode\\u003enpx create-remix@latest --template \\u0026#x3C;org\\u003e/\\u0026#x3C;repo\\u003e\\\\n\\u003c/code\\u003e\\u003c/pre\\u003e\\\\n\\u003cp\\u003eYou can read more about templates in the \\u003ca href=\\\\\\\"../guides/templates\\\\\\\"\\u003eTemplates Guide\\u003c/a\\u003e.\\u003c/p\\u003e\\\\n\\u003cp\\u003eOnce you've picked a template or \\u003ca href=\\\\\\\"../start/quickstart\\\\\\\"\\u003eset up an app from scratch\\u003c/a\\u003e, you're ready to start building your app!\\u003c/p\\u003e\\\",\\\"docs/discussion/runtimes\\\",\\\"headings\\\",[960,965,968,972],{\\\"_961\\\":962,\\\"_955\\\":963,\\\"_24\\\":964},\\\"headingLevel\\\",\\\"h2\\\",\\\"JavaScript Runtimes\\\",\\\"javascript-runtimes\\\",{\\\"_961\\\":962,\\\"_955\\\":966,\\\"_24\\\":967},\\\"Adapters\\\",\\\"adapters\\\",{\\\"_961\\\":969,\\\"_955\\\":970,\\\"_24\\\":971},\\\"h3\\\",\\\"Remix App Server\\\",\\\"remix-app-server\\\",{\\\"_961\\\":962,\\\"_955\\\":932,\\\"_24\\\":973},\\\"templates\\\",[],\\\"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/discussion/runtimes",
|
|
"metadata": {
|
|
"description": "",
|
|
"headings": [
|
|
"Runtimes, Adapters, Templates, and Deployment",
|
|
"JavaScript Runtimes",
|
|
"Adapters",
|
|
"Remix App Server",
|
|
"Templates"
|
|
],
|
|
"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/discussion/runtimes/#javascript-runtimes",
|
|
"/docs/discussion/runtimes/#adapters",
|
|
"/docs/discussion/runtimes/#remix-app-server",
|
|
"/docs/discussion/runtimes/#templates",
|
|
"https://npm.im/@remix-run/cloudflare-pages",
|
|
"https://npm.im/@remix-run/cloudflare-workers",
|
|
"https://npm.im/@remix-run/deno",
|
|
"https://npm.im/@remix-run/node",
|
|
"../other-api/serve",
|
|
"../guides/templates",
|
|
"../start/quickstart",
|
|
"https://remix.run",
|
|
"https://opensource.org/licenses/MIT",
|
|
"https://github.com/remix-run/remix-v2-website/edit/main/data/docs/discussion/runtimes.md"
|
|
]
|
|
},
|
|
"hash": "51e57a61094ebd4bce28f45edb7f8f24c5fdea1b5863486dd0e2294f6066432a",
|
|
"timestamp": "2026-02-23T11:36:17.621620244+01:00"
|
|
} |