diff --git a/docs/components/form.md b/docs/components/form.md index 31aedd02aa0..451dad0118c 100644 --- a/docs/components/form.md +++ b/docs/components/form.md @@ -25,8 +25,8 @@ function NewEvent() { - Whether JavaScript is on the page or not, your data interactions created with `
` and `action` will work. - After a `` submission, all of the loaders on the page will be reloaded. This ensures that any updates to your data are reflected in the UI. -- `` automatically serializes your form's values (identically to the browser when not using JavaScript) -- You can build "optimistic UI" and pending indicators with [`useTransition`][usetransition] +- `` automatically serializes your form's values (identically to the browser when not using JavaScript). +- You can build "optimistic UI" and pending indicators with [`useTransition`][usetransition]. ## `action` diff --git a/docs/components/link.md b/docs/components/link.md index 633138d0c0d..dbc52b29f68 100644 --- a/docs/components/link.md +++ b/docs/components/link.md @@ -34,7 +34,7 @@ In the effort to remove all loading states from your UI, `Link` can automaticall ``` - **"none"** - Default behavior. This will prevent any prefetching from happening. This is recommended when linking to pages that require a user session that the browser won't be able to prefetch anyway. -- **"intent"** - Recommended if you want to prefetch. Fetches when Remix thinks the user intends to visit the link. Right now the behavior is simple: if they hover or focus the link it will prefetch the resources. In the future we hope to make this even smarter. Links with large click areas/padding get a bit of a head start. It is worth noting that when using `prefetch="intent"`, `` elements will be inserted on hover/focus and removed if the `` loses hover/focus. Without proper `cache-control` headers on your loaders this could result in repeated prefetch loads if a user continually hovers on and off a link. +- **"intent"** - Recommended if you want to prefetch. Fetches when Remix thinks the user intends to visit the link. Right now the behavior is simple: if they hover or focus the link it will prefetch the resources. In the future we hope to make this even smarter. Links with large click areas/padding get a bit of a head start. It is worth noting that when using `prefetch="intent"`, `` elements will be inserted on hover/focus and removed if the `` loses hover/focus. Without proper `cache-control` headers on your loaders, this could result in repeated prefetch loads if a user continually hovers on and off a link. - **"render"** - Fetches when the link is rendered. You may need to use the :last-of-type selector instead of :last-child when styling child elements inside of your links diff --git a/docs/file-conventions/entry.server.md b/docs/file-conventions/entry.server.md index 91a4e244c93..a043e82da72 100644 --- a/docs/file-conventions/entry.server.md +++ b/docs/file-conventions/entry.server.md @@ -9,7 +9,7 @@ Remix uses `app/entry.server.tsx` (or `.jsx`) to generate the HTTP response when This module should render the markup for the current page using a `` element with the `context` and `url` for the current request. This markup will (optionally) be re-hydrated once JavaScript loads in the browser using the [browser entry module][browser-entry-module]. -You can also 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. +You can also 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. Here's a basic example: diff --git a/docs/guides/constraints.md b/docs/guides/constraints.md index bb95b3beb2e..5978bd98a14 100644 --- a/docs/guides/constraints.md +++ b/docs/guides/constraints.md @@ -4,7 +4,7 @@ title: Module Constraints # Module Constraints -In order for Remix to run your app in both the server and browser environments, your application modules and third party dependencies need to be careful about **module side effects**. +In order for Remix to run your app in both the server and browser environments, your application modules and third-party dependencies need to be careful about **module side effects**. - **Server-only code** - Remix will remove server-only code but it can't if you have module side effects that use server-only code. - **Browser-only code** - Remix renders on the server so your modules can't have module side effects or first-rendering logic that call browser-only APIs @@ -257,9 +257,9 @@ export async function redirectToStripeCheckout(sessionId) { You need to avoid any browser-only module side effects like accessing window or initializing APIs in the module scope. -### Initializing Browser Only APIs +### Initializing Browser-Only APIs -The most common scenario is initializing a third party API when your module is imported. There are a couple ways to easily deal with this. +The most common scenario is initializing a third-party API when your module is imported. There are a couple ways to easily deal with this. #### Document Guard diff --git a/docs/hooks/use-action-data.md b/docs/hooks/use-action-data.md index 6dfaf5cc0f6..1b497f283a4 100644 --- a/docs/hooks/use-action-data.md +++ b/docs/hooks/use-action-data.md @@ -103,7 +103,7 @@ When using `` (instead of `` or ``), Remix _doe Remix client-side navigation does not resubmit forms on pop events like browsers. -Form submissions are navigation events in browsers (and Remix), which means users can click the back button into a location that had a form submission _and the browser will resubmit the form_. You usually don't ever want this to happen. +Form submissions are navigation events in browsers (and Remix), which means users can click the back button into a location that had a form submission _and the browser will resubmit the form_. You usually don't want this to happen. For example, consider this user flow: diff --git a/docs/hooks/use-fetcher.md b/docs/hooks/use-fetcher.md index 3d6fcf324a3..7190757d897 100644 --- a/docs/hooks/use-fetcher.md +++ b/docs/hooks/use-fetcher.md @@ -26,7 +26,7 @@ It is common for Remix newcomers to see this hook and think it is the primary wa - [`useActionData`][useactiondata] - [`useTransition`][usetransition] -If you're building a highly interactive, "app like" user interface, you will use `useFetcher` often. +If you're building a highly interactive, "app-like" user interface, you will use `useFetcher` often. ```tsx import { useFetcher } from "@remix-run/react"; @@ -65,9 +65,9 @@ Notes about how it works: You can know the state of the fetcher with `fetcher.state`. It will be one of: -- **idle** - nothing is being fetched. +- **idle** - Nothing is being fetched. - **submitting** - A form has been submitted. If the method is GET, then the route loader is being called. If POST, PUT, PATCH, or DELETE, then the route action is being called. -- **loading** - The loaders for the routes are being reloaded after an action submission +- **loading** - The loaders for the routes are being reloaded after an action submission. #### `fetcher.type` @@ -239,7 +239,7 @@ function NewsletterSignup() { You can still provide a no-JavaScript experience -Because `useFetcher` doesn't cause a navigation, it won't automatically work if there is no JavaScript on the page like a normal Remix `` will because the browser will still navigate to the form's action. +Because `useFetcher` doesn't cause a navigation, it won't automatically work if there is no JavaScript on the page like a normal Remix `` will, because the browser will still navigate to the form's action. If you want to support a no JavaScript experience, just export a component from the route with the action. @@ -267,7 +267,7 @@ export default function NewsletterSignupRoute() { } ``` -- When JS is on the page, the user will subscribe to the newsletter and the page won't change, they'll just get a solid, dynamic experience +- When JS is on the page, the user will subscribe to the newsletter and the page won't change, they'll just get a solid, dynamic experience. - When JS is not on the page, they'll be transitioned to the signup page by the browser. You could even refactor the component to take props from the hooks and reuse it: @@ -321,7 +321,7 @@ export default function NewsletterSignupRoute() { **Mark Article as Read** -Imagine you want to mark an article has been read by the current user after they've been on the page for a while and scrolled to the bottom, you could make a hook that looks something like this: +Imagine you want to mark that an article has been read by the current user, after they've been on the page for a while and scrolled to the bottom. You could make a hook that looks something like this: ```tsx function useMarkAsRead({ articleId, userId }) { diff --git a/docs/other-api/adapter.md b/docs/other-api/adapter.md index c2cf17080d8..bab8f2e5904 100644 --- a/docs/other-api/adapter.md +++ b/docs/other-api/adapter.md @@ -16,7 +16,7 @@ Idiomatic Remix apps can generally be deployed anywhere because Remix adapt's th - `@remix-run/netlify` - `@remix-run/vercel` -These adapters are imported into your server's entry and is not used inside of your Remix app itself. +These adapters are imported into your server's entry and are not used inside of your Remix app itself. If you initialized your app with `npx create-remix@latest` with something other than the built-in Remix App Server, you will note a `server/index.js` file that imports and uses one of these adapters. @@ -135,7 +135,7 @@ import * as build from "../build"; addEventListener("fetch", createEventHandler({ build })); ``` -Here's an example with the lower level Cloudflare Workers API: +Here's an example with the lower-level Cloudflare Workers API: ```ts import { diff --git a/docs/other-api/dev.md b/docs/other-api/dev.md index cd2b82b3f9a..61a6a676949 100644 --- a/docs/other-api/dev.md +++ b/docs/other-api/dev.md @@ -88,7 +88,7 @@ Attaches a [Node inspector][node-inspector] to develop your app in debug mode. Launches the app server on a given port. -By default, the port is set to `3000`. If port `3000` is unavailable, the `dev` command will attempt to find another port that is open. Using the `--port` flag will only attempt to launch the server at the given port; if the port is unavailable the app will not start. +By default, the port is set to `3000`. If port `3000` is unavailable, the `dev` command will attempt to find another port that is open. Using the `--port` flag will only attempt to launch the server at the given port; if the port is unavailable, the app will not start. ```sh remix dev --port 4001 diff --git a/docs/other-api/serve.md b/docs/other-api/serve.md index 3c2d4c7627d..83832ee3a07 100644 --- a/docs/other-api/serve.md +++ b/docs/other-api/serve.md @@ -6,7 +6,7 @@ order: 3 # Remix App Server -While you can bring your own server, Remix ships with a built-in, production ready application server. +While you can bring your own server, Remix ships with a built-in, production-ready application server. ```sh remix-serve diff --git a/docs/route/action.md b/docs/route/action.md index fc1ca2fe31a..57bb6e38d5d 100644 --- a/docs/route/action.md +++ b/docs/route/action.md @@ -6,7 +6,7 @@ title: action Watch the 📼 Remix Singles: Data Mutations with Form + action and Multiple Forms and Single Button Mutations -Like `loader`, action is a server only function to handle data mutations and other actions. If a non-GET request is made to your route (POST, PUT, PATCH, DELETE) then the action is called before the loaders. +Like `loader`, action is a server-only function to handle data mutations and other actions. If a non-GET request is made to your route (POST, PUT, PATCH, DELETE) then the action is called before the loaders. Actions have the same API as loaders, the only difference is when they are called. diff --git a/docs/route/loader.md b/docs/route/loader.md index ac49b65c175..ca6e173f4ee 100644 --- a/docs/route/loader.md +++ b/docs/route/loader.md @@ -18,7 +18,7 @@ export const loader = async () => { This function is only ever run on the server. On the initial server render it will provide data to the HTML document, On navigations in the browser, Remix will call the function via [`fetch`][fetch] from the browser. -This means you can talk directly to your database, use server only API secrets, etc. Any code that isn't used to render the UI will be removed from the browser bundle. +This means you can talk directly to your database, use server-only API secrets, etc. Any code that isn't used to render the UI will be removed from the browser bundle. Using the database ORM Prisma as an example: diff --git a/docs/route/meta.md b/docs/route/meta.md index c1e97c28fa4..69c54808416 100644 --- a/docs/route/meta.md +++ b/docs/route/meta.md @@ -122,7 +122,7 @@ const meta: MetaFunction< Meta is changing in v2, you can opt in to the new API today, [see the meta v2 section][meta-v2], but you don't have to until you're ready. -You can enable the new meta API with a future flag in `remix.config.js` +You can enable the new meta API with a future flag in `remix.config.js`. ```js filename=remix.config.js module.exports = { @@ -187,7 +187,7 @@ const title = { This is a list of the current route matches. You have access many things, particularly the meta from the parent matches and data. -It's most useful for merging the parent meta into the child meta since the child meta value is what will be used: +It's most useful for merging the parent meta into the child meta since the child-meta value is what will be used: ```tsx export const meta: V2_MetaFunction = ({ matches }) => { @@ -216,7 +216,7 @@ export const meta: V2_MetaFunction = ({ ## `parentsData` -Often you'll need the data from a parent route, you can look it up by route ID on `parentsData` +Often you'll need the data from a parent route, you can look it up by route ID on `parentsData`. ```tsx filename=routes/project/$pid/tasks/$tid.tsx import type { loader as projectDetailsLoader } from "../../../$pid"; @@ -312,7 +312,7 @@ export default function Root() { ### Avoid Meta in Parent Routes -You can also avoid the merge problem by simply not exporting meta that you want to override from parent routes. Instead of defining meta on the parent route, use the \[index route]\[index-route]. This way you can avoid complex merge logic for things the title. Otherwise you will need to find the parent title descriptor and replace it with the child's title. It's much easier to simply not need to override by using index routes. +You can also avoid the merge problem by simply not exporting meta that you want to override from parent routes. Instead of defining meta on the parent route, use the [index route][index-route]. This way you can avoid complex merge logic for things like the title. Otherwise you will need to find the parent title descriptor and replace it with the child's title. It's much easier to simply not need to override by using index routes. ### Merging with Parent Meta @@ -340,6 +340,6 @@ If you can't avoid the merge problem with global meta or index routes, we've cre [meta-v2]: #metav2 [root-route]: ../file-conventions/root [matches]: #matches -[index-routes]: ../guides/routing#index-routes +[index-route]: ../guides/routing#index-routes [merge-meta]: https://gist.github.com/ryanflorence/ec1849c6d690cfbffcb408ecd633e069 [url-params]: ../guides/routing#dynamic-segments diff --git a/docs/route/should-revalidate.md b/docs/route/should-revalidate.md index 3248aa6258f..b8aaa5df957 100644 --- a/docs/route/should-revalidate.md +++ b/docs/route/should-revalidate.md @@ -4,7 +4,7 @@ title: shouldRevalidate # `shouldRevalidate` -This function lets apps optimize which routes data should be reloaded after actions and for client side navigations. +This function lets apps optimize which routes data should be reloaded after actions and for client-side navigations. ```ts import type { ShouldRevalidateFunction } from "@remix-run/react"; @@ -85,7 +85,7 @@ export function shouldRevalidate() { ## `currentParams` -These are the \[URL params]\[url-params] from the URL that can be compared to the `nextParams` to decide if you need to reload or not. Perhaps you're using only a partial piece of the param for data loading, you don't need to revalidate if a superfluous part of the param changed. +These are the [URL params][url-params] from the URL that can be compared to the `nextParams` to decide if you need to reload or not. Perhaps you're using only a partial piece of the param for data loading, you don't need to revalidate if a superfluous part of the param changed. For instance, consider an event slug with the id and an human-friendly title: @@ -119,7 +119,7 @@ This is the url the navigation started from. ## `nextParams` -In the case of navigation, these are the \[URL params]\[url-params] from the next location the user is requesting. Some revalidations are not navigation, so it will simply be the same as `currentParams`. +In the case of navigation, these are the [URL params][url-params] from the next location the user is requesting. Some revalidations are not navigation, so it will simply be the same as `currentParams`. ## `nextUrl` @@ -242,3 +242,5 @@ export function shouldRevalidate({ return defaultShouldRevalidate; } ``` + +[url-params]: ../guides/routing#dynamic-segments diff --git a/docs/utils/cookies.md b/docs/utils/cookies.md index 56c2f1f065c..f59db214971 100644 --- a/docs/utils/cookies.md +++ b/docs/utils/cookies.md @@ -191,7 +191,7 @@ console.log(isCookie(cookie)); ## Cookie API -A cookie container is returned from `createCookie` and has handful of properties and methods. +A cookie container is returned from `createCookie` and has a handful of properties and methods. ```ts const cookie = createCookie(name); diff --git a/docs/utils/sessions.md b/docs/utils/sessions.md index af56f4f9eb5..1298920b35b 100644 --- a/docs/utils/sessions.md +++ b/docs/utils/sessions.md @@ -255,7 +255,7 @@ The `expires` argument to `createData` and `updateData` is the same `Date` at wh For purely cookie-based sessions (where the session data itself is stored in the session cookie with the browser, see [cookies][cookies]) you can use `createCookieSessionStorage()`. -The main advantage of cookie session storage is that you don't need any additional backend services or databases to use it. It can also be beneficial in some load balanced scenarios. However, cookie-based sessions may not exceed the browser's max allowed cookie length (typically 4kb). +The main advantage of cookie session storage is that you don't need any additional backend services or databases to use it. It can also be beneficial in some load-balanced scenarios. However, cookie-based sessions may not exceed the browser's max-allowed cookie length (typically 4kb). The downside is that you have to `commitSession` in almost every loader and action. If your loader or action changes the session at all, it must be committed. That means if you `session.flash` in an action, and then `session.get` in another, you must commit it for that flashed message to go away. With other session storage strategies you only have to commit it when it's created (the browser cookie doesn't need to change because it doesn't store the session data, just the key to find it elsewhere). @@ -334,7 +334,7 @@ export { getSession, commitSession, destroySession }; For [Cloudflare Workers KV][cloudflare-kv] backed sessions, use `createWorkersKVSessionStorage()`. -The advantage of KV backed sessions is that only the session ID is stored in the cookie while the rest of the data is stored in a globally replicated, low-latency data store with exceptionally high read volumes with low-latency. +The advantage of KV backed sessions is that only the session ID is stored in the cookie while the rest of the data is stored in a globally-replicated, low-latency data store with exceptionally high-read volumes with low-latency. ```js filename=app/sessions.server.js import { @@ -400,7 +400,7 @@ export { getSession, commitSession, destroySession }; ## Session API -After retrieving a session with `getSession`, the session object returned has a handful of methods and properties: +After retrieving a session with `getSession`, the returned session object has a handful of methods and properties: ```tsx export async function action({ request }: ActionArgs) { @@ -462,7 +462,7 @@ export async function action({ Now we can read the message in a loader. -You must commit the session whenever you read a `flash`. This is different than you might be used to where some type of middleware automatically sets the cookie header for you. +You must commit the session whenever you read a `flash`. This is different than what you might be used to, where some type of middleware automatically sets the cookie header for you. ```tsx import { json } from "@remix-run/node"; // or cloudflare/deno