You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/file-conventions/entry.client.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,9 +5,9 @@ toc: false
5
5
6
6
# entry.client
7
7
8
-
By default, Remix will handle hydrating your app on the client for you. If you want to customize this behavior, you can run `npx remix reveal` to generate a `app/entry.client.tsx` (or `.jsx`) that will take precedence. This file is the entry point for the browser and is responsible for hydrating the markup generated by the server in your [server entry module][server_entry_module], however you can also initialize any other client-side code here.
8
+
By default, Remix will handle hydrating your app on the client for you. If you want to customize this behavior, you can run `npx remix reveal` to generate a `app/entry.client.tsx` (or `.jsx`) that will take precedence. This file is the entry point for the browser and is responsible for hydrating the markup generated by the server in your [server entry module][server_entry_module]; however, you can also initialize any other client-side code here.
9
9
10
-
Typically, this module uses `ReactDOM.hydrateRoot` to hydrate the markup that was already generated on the server in your [server entry module][server_entry_module].
10
+
Typically, this module uses `ReactDOM.hydrateRoot` to hydrate the markup already generated on the server in your [server entry module][server_entry_module].
11
11
12
12
Here's a basic example:
13
13
@@ -26,6 +26,6 @@ startTransition(() => {
26
26
});
27
27
```
28
28
29
-
This is the first piece of code that runs in the browser. You can initialize client side libraries, add clientonly providers, etc.
29
+
This is the first piece of code that runs in the browser. You can initialize client side libraries, add client-only providers, etc.
Copy file name to clipboardExpand all lines: docs/file-conventions/entry.server.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,7 +11,7 @@ This module should render the markup for the current page using a `<RemixServer>
11
11
12
12
## `handleDataRequest`
13
13
14
-
You can export an optional `handleDataRequest` function that will allow you to modify the response of a data request. These are the requests that do not render HTML, but rather return the loader and action data to the browser once client-side hydration has occurred.
14
+
You can export an optional `handleDataRequest` function that will allow you to modify the response of a data request. These are the requests that do not render HTML but rather return the loader and action data to the browser once client-side hydration has occurred.
15
15
16
16
```tsx
17
17
exportfunction handleDataRequest(
@@ -51,7 +51,7 @@ _Note that you generally want to avoid logging when the request was aborted, sin
51
51
52
52
### Streaming Rendering Errors
53
53
54
-
When you are streaming your HTML responses via [`renderToPipeableStream`][rendertopipeablestream] or [`renderToReadableStream`][rendertoreadablestream], your own `handleError` implementation will only handle errors encountered during the initial shell render. If you encounter a rendering error during subsequent streamed rendering you will need to handle these errors manually since the Remix server has already sent the Response by that point.
54
+
When you are streaming your HTML responses via [`renderToPipeableStream`][rendertopipeablestream] or [`renderToReadableStream`][rendertoreadablestream], your own `handleError` implementation will only handle errors encountered during the initial shell render. If you encounter a rendering error during subsequent streamed rendering, you will need to handle these errors manually since the Remix server has already sent the Response by that point.
55
55
56
56
- For `renderToPipeableStream`, you can handle these errors in the `onError` callback function. You will need to toggle a boolean in `onShellReady` so you know if the error was a shell rendering error (and can be ignored) or an async rendering error (and must be handled).
57
57
- For an example, please refer to the default [`entry.server.tsx`][node-streaming-entry-server] for Node.
@@ -60,7 +60,7 @@ When you are streaming your HTML responses via [`renderToPipeableStream`][render
60
60
61
61
### Thrown Responses
62
62
63
-
Note that this does not handle thrown `Response` instances from your `loader`/`action` functions. The intention of this handler is to find bugs in your code which result in unexpected thrown errors. If you are detecting a scenario and throwing a 401/404/etc. `Response` in your `loader`/`action` then it's an expected flow that is handled by your code. If you also wish to log, or send those to an external service, that should be done at the time you throw the response.
63
+
Note that this does not handle thrown `Response` instances from your `loader`/`action` functions. The intention of this handler is to find bugs in your code which result in unexpected thrown errors. If you are detecting a scenario and throwing a 401/404/etc. `Response` in your `loader`/`action` then it's an expected flow handled by your code. If you also wish to log or send those to an external service, that should be done at the time you throw the response.
Copy file name to clipboardExpand all lines: docs/file-conventions/remix-config.md
+5-5Lines changed: 5 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,7 +7,7 @@ hidden: true
7
7
8
8
<docs-warning>`remix.config.js` is only relevant when using the [Classic Remix Compiler][classic-remix-compiler]. When using [Remix Vite][remix-vite], this file should not be present in your project. Instead, Remix configuration should be provided to the Remix plugin in your [Vite config][vite-config].</docs-warning>
9
9
10
-
This file has a few build and development configuration options, but does not actually run on your server.
10
+
This file has a few build and development configuration options but does not run on your server.
The path to the browser build, relative to remix.config.js. Defaults to
47
-
"public/build". Should be deployed to static hosting.
47
+
`"public/build"`. Should be deployed to static hosting.
48
48
49
49
## browserNodeBuiltinsPolyfill
50
50
@@ -95,7 +95,7 @@ module.exports = {
95
95
};
96
96
```
97
97
98
-
If you wish to serve static assets from a separate domain you may also specify an absolute path:
98
+
If you wish to serve static assets from a separate domain, you may also specify an absolute path:
99
99
100
100
```js filename=remix.config.js
101
101
/**@type{import('@remix-run/dev').AppConfig}*/
@@ -163,7 +163,7 @@ field in `package.json`.
163
163
164
164
A list of regex patterns that determines if a module is transpiled and included
165
165
in the server bundle. This can be useful when consuming ESM only packages in a
166
-
CJS build, or when consuming packages with [CSS side effect
166
+
CJS build or when consuming packages with [CSS side effect
167
167
imports][css_side_effect_imports].
168
168
169
169
For example, the `unified` ecosystem is all ESM-only. Let's also say we're using
@@ -234,7 +234,7 @@ The platform the server build is targeting, which can either be `"neutral"` or
234
234
235
235
## tailwind
236
236
237
-
Whether to support [Tailwind functions and directives][tailwind_functions_and_directives] in CSS files if `tailwindcss` is installed. Defaults to `true`.
237
+
Whether to support [Tailwind CSS functions and directives][tailwind_functions_and_directives] in CSS files if `tailwindcss` is installed. Defaults to `true`.
Copy file name to clipboardExpand all lines: docs/file-conventions/root.md
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,7 +7,7 @@ toc: false
7
7
8
8
The "root" route (`app/root.tsx`) is the only _required_ route in your Remix application because it is the parent to all routes in your `routes/` directory and is in charge of rendering the root `<html>` document.
9
9
10
-
Beyond that, it's mostly just like any other route and supports all of the standard route exports:
10
+
Beyond that, it's mostly just like any other route and supports all the standard route exports:
11
11
12
12
-[`headers`][headers]
13
13
-[`meta`][meta]
@@ -22,7 +22,7 @@ Beyond that, it's mostly just like any other route and supports all of the stand
22
22
-[`handle`][handle]
23
23
-[`shouldRevalidate`][shouldrevalidate]
24
24
25
-
Because the root route manages your document, it is the proper place to render a handful of "document-level" components Remix provides. These components are to be used once inside your root route and they include everything Remix figured out or built in order for your page to render properly.
25
+
Because the root route manages your document, it is the proper place to render a handful of "document-level" components Remix provides. These components are to be used once inside your root route, and they include everything Remix figured out or built in order for your page to render properly.
26
26
27
27
```tsx filename=app/root.tsx
28
28
importtype { LinksFunction } from"@remix-run/node"; // or cloudflare/deno
@@ -81,7 +81,7 @@ export default function App() {
81
81
82
82
## Layout Export
83
83
84
-
Because the root route manages the document for all routes, it also supports an additional optional `Layout` export. You can read the details in this [RFC][layout-rfc] but the layout route serves 2 purposes:
84
+
Because the root route manages the document for all routes, it also supports an additional optional `Layout` export. You can read the details in this [RFC][layout-rfc] but the layout route serves two purposes:
85
85
86
86
- Avoid duplicating your document/"app shell" across your root component, `HydrateFallback`, and `ErrorBoundary`
87
87
- Avoids React from re-mounting your app shell elements when switching between the root component/`HydrateFallback`/`ErrorBoundary` which can cause a FOUC if React removes and re-adds `<link rel="stylesheet">` tags from your `<Links>` component.
@@ -148,7 +148,7 @@ export function ErrorBoundary() {
148
148
149
149
**A note on `useLoaderData`in the `Layout` Component**
150
150
151
-
`useLoaderData` is not permitted to be used in `ErrorBoundary` components because it is intended for the happy-path route rendering, and its typings have a built-in assumption that the `loader` ran successfully and returned something. That assumption doesn't hold in an `ErrorBoundary` because it could have been the `loader` that threw and triggered the boundary! In order to access loader data in `ErrorBoundary`'s, you can use `useRouteLoaderData` which accounts for the loader data potentially being `undefined`.
151
+
`useLoaderData` is not permitted to be used in `ErrorBoundary` components because it is intended for the happy-path route rendering, and its typings have a built-in assumption that the `loader` ran successfully and returned something. That assumption doesn't hold in an `ErrorBoundary` because it could have been the `loader` that threw and triggered the boundary! To access loader data in `ErrorBoundary`'s, you can use `useRouteLoaderData` which accounts for the loader data potentially being `undefined`.
152
152
153
153
Because your `Layout` component is used in both success and error flows, this same restriction holds. If you need to fork logic in your `Layout` depending on if it was a successful request or not, you can use `useRouteLoaderData("root")` and `useRouteError()`.
Copy file name to clipboardExpand all lines: docs/file-conventions/routes.md
+8-8Lines changed: 8 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,17 +12,17 @@ Please note that you can use either `.js`, `.jsx`, `.ts` or `.tsx` file extensio
12
12
13
13
## Disclaimer
14
14
15
-
Before we go too far into the Remix convention though, we'd like to point out that file-based routing is an **incredibly** subjective idea. Some folks love the "flat" routes idea, some folks hate it and would prefer nesting routes in folders. Some folks simply hate file-based routing and would prefer to configure routes via JSON. Some folks would prefer to configure routes via JSX like they did in their React Router SPA's.
15
+
Before we go too far into the Remix convention, though, we'd like to point out that file-based routing is an **incredibly** subjective idea. Some folks love the "flat" routes idea, some folks hate it and would prefer nesting routes in folders. Some folks simply hate file-based routing and would prefer to configure routes via JSON. Some folks would prefer to configure routes via JSX like they did in their React Router SPA's.
16
16
17
17
The point is, we are well aware of this and from the get-go, Remix has always given you a first-class way to opt-out via the [`routes`][routes_config]/[`ignoredRouteFiles`][ignoredroutefiles_config] and [configure your routes manually][manual-route-configuration]. But, there has to be _some_ default so that folks can get up and running quickly and easily - and we think that the flat routes convention document below is a pretty good default that scales well for small-to-medium sized apps.
18
18
19
-
Large applications with hundreds or thousands of routes will _always_ be a bit chaotic no matter what convention you use - and the idea is that via the `routes` config, you get to build _exactly_ the convention that works best for your application/team. It would be quite literally impossible for Remix to have a default convention that made everyone happy. We'd much rather give you a fairly straightforward default, and then let the community build any number of conventions you can pick and choose from.
19
+
Large applications with hundreds or thousands of routes will _always_ be a bit chaotic no matter what convention you use — and the idea is that via the `routes` config, you get to build _exactly_ the convention that works best for your application/team. It would be quite literally impossible for Remix to have a default convention that made everyone happy. We'd much rather give you a fairly straightforward default and then let the community build any number of conventions you can pick and choose from.
20
20
21
-
So, before we dive into the details of the Remix default convention, here's some community alternatives you can check out if you decide that our default is not your cup of tea.
21
+
So, before we dive into the details of the Remix default convention, here are some community alternatives you can check out if you decide that our default is not your cup of tea.
22
22
23
-
-[`remix-flat-routes`][flat_routes] - The Remix default is basically a simplified version of this package. The author has continued to iterate on and evolve this package so if you generally like the "flat routes" idea but want a bit more power (including a hybrid approach of files and folders), definitely check this one out.
23
+
-[`remix-flat-routes`][flat_routes] - The Remix default is basically a simplified version of this package. The author has continued to iterate on and evolve this package, so if you generally like the "flat routes" idea but want a bit more power (including a hybrid approach of files and folders), definitely check this one out.
24
24
-[`remix-custom-routes`][custom_routes] - If you want even more customization, this package lets you define that types of files should be treated as routes. This lets you go beyond the simple flat/nested concept and do something such as _"any file with an extension of `.route.tsx` is a route"_.
25
-
-[`remix-json-routes`][json_routes] - If you just want to specify your routes via a config file, this is your jam - just provide Remix a JSON object with your routes and skip the flat/nested concept entirely. There's even a JSX option in there too.
25
+
-[`remix-json-routes`][json_routes] - If you just want to specify your routes via a config file, this is your jam — provide Remix a JSON object with your routes and skip the flat/nested concept entirely. There's even a JSX option in there too.
26
26
27
27
## Root Route
28
28
@@ -227,7 +227,7 @@ Think of the `trailing_` underscore as the long bit at the end of your parent's
227
227
228
228
We call these <aname="pathless-routes"><b>Pathless Routes</b></a>
229
229
230
-
Sometimes you want to share a layout with a group of routes without adding any path segments to the URL. A common example is a set of authentication routes that have a different header/footer than the public pages or the logged in app experience. You can do this with a `_leading` underscore.
230
+
Sometimes you want to share a layout with a group of routes without adding any path segments to the URL. A common example is a set of authentication routes that have a different header/footer than the public pages or the logged-in-app experience. You can do this with a `_leading` underscore.
231
231
232
232
```text lines=[3-5]
233
233
app/
@@ -274,7 +274,7 @@ Wrapping a route segment in parentheses will make the segment optional.
You may wonder why `/american-flag-speedo` is matching the `($lang)._index.tsx` route instead of `($lang).$productId.tsx`. This is because when you have an optional dynamic param segment followed by another dynamic param, Remix cannot reliably determine if a single-segment URL such as `/american-flag-speedo` should match `/:lang``/:productId`. Optional segments match eagerly and thus it will match `/:lang`. If you have this type of setup it's recommended to look at `params.lang` in the `($lang)._index.tsx` loader and redirect to `/:lang/american-flag-speedo` for the current/default language if `params.lang` is not a valid language code.
277
+
You may wonder why `/american-flag-speedo` is matching the `($lang)._index.tsx` route instead of `($lang).$productId.tsx`. This is because when you have an optional dynamic param segment followed by another dynamic param, Remix cannot reliably determine if a single-segment URL such as `/american-flag-speedo` should match `/:lang``/:productId`. Optional segments match eagerly and thus it will match `/:lang`. If you have this type of setup, it's recommended to look at `params.lang` in the `($lang)._index.tsx` loader and redirect to `/:lang/american-flag-speedo` for the current/default language if `params.lang` is not a valid language code.
Our general recommendation for scale is to make every route a folder and put the modules used exclusively by that route in the folder, then put the shared modules outside of routes folder elsewhere. This has a couple benefits:
398
+
Our general recommendation for scale is to make every route a folder and put the modules used exclusively by that route in the folder, then put the shared modules outside the `routes` folder elsewhere. This has a couple of benefits:
399
399
400
400
- Easy to identify shared modules, so tread lightly when changing them
401
401
- Easy to organize and refactor the modules for a specific route without creating "file organization fatigue" and cluttering up other parts of the app
Copy file name to clipboardExpand all lines: docs/file-conventions/vite-config.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -108,7 +108,7 @@ The path to the build directory, relative to the project root. Defaults to
108
108
109
109
#### basename
110
110
111
-
An optional basename for your route paths, passed through to the [React Router "basename" option][rr-basename]. Please note that this is different from your _asset_ paths. You can can configure the [base public path][vite-public-base-path] for your assets via the [Vite "base" option][vite-base].
111
+
An optional basename for your route paths, passed through to the [React Router "basename" option][rr-basename]. Please note that this is different from your _asset_ paths. You can configure the [base public path][vite-public-base-path] for your assets via the [Vite "base" option][vite-base].
112
112
113
113
#### buildEnd
114
114
@@ -125,7 +125,7 @@ An array of [presets] to ease integration with other tools and hosting providers
125
125
126
126
#### serverBuildFile
127
127
128
-
The name of the server file generated in the server build directory. Defaults to `"index.js"`.
128
+
The name of the server file is generated in the server build directory. Defaults to `"index.js"`.
0 commit comments