Skip to content

Commit

Permalink
Merge branch 'main' into patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
irsooti committed Jan 30, 2023
2 parents a95ca50 + f3de6e4 commit b0f1985
Show file tree
Hide file tree
Showing 109 changed files with 849 additions and 247 deletions.
6 changes: 6 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ body:
label: What version of Remix are you using?
validations:
required: true
- type: checkboxes
attributes:
label: Are all your remix dependencies & dev-dependencies using the same version?
options:
- label: "Yes"
required: true
- type: textarea
attributes:
label: Steps to Reproduce
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
SHORT_SHA=${SHA::7}
# get latest nightly tag
LATEST_NIGHTLY_TAG=$(git tag -l v0.0.0-nightly-\* --sort=-committerdate | head -n 1)
LATEST_NIGHTLY_TAG=$(git tag -l v0.0.0-nightly-\* --sort=-creatordate | head -n 1)
# check if last commit to dev starts would be the nightly tag we're about to create (minus the date)
# if it is, we'll skip the nightly creation
Expand Down
9 changes: 9 additions & 0 deletions contributors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
- craigglennie
- crismali
- cysp
- d4vsanchez
- dabdine
- daganomri
- damiensedgwick
Expand All @@ -101,6 +102,7 @@
- Deanmv
- denissb
- derekr
- derenge
- developit
- dgurns
- dhargitai
Expand Down Expand Up @@ -186,6 +188,7 @@
- jacargentina
- jacob-ebey
- JacobParis
- jakeginnivan
- jakewtaylor
- jamiebuilds
- janhoogeveen
Expand All @@ -203,6 +206,7 @@
- jiahao-c
- jimniels
- jkup
- jly36963
- jmasson
- jmorel88
- JNaftali
Expand Down Expand Up @@ -288,6 +292,7 @@
- mantey-github
- manzano78
- manzoorwanijk
- marceltn
- marcisbee
- marcomafessolli
- markdalgleish
Expand Down Expand Up @@ -357,6 +362,7 @@
- pcattori
- penspinner
- penx
- petetnt
- philandstuff
- phishy
- plastic041
Expand Down Expand Up @@ -462,6 +468,7 @@
- wKovacs64
- wladiston
- wtlin1228
- xHomu
- XiNiHa
- xstevenyung
- yauri-io
Expand All @@ -471,6 +478,8 @@
- youngvform
- zachdtaylor
- zainfathoni
- zayenz
- zhe
- mitchelldirt
- krolebord
- panteliselef
1 change: 1 addition & 0 deletions docs/components/await.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: Await
toc: false
---

# `<Await>`
Expand Down
5 changes: 5 additions & 0 deletions docs/components/form.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ title: Form

# `<Form>`

<docs-info>This component is simply a re-export of [React Router's `Form`][rr-form].</docs-info>

<docs-success>Watch the <a href="https://www.youtube.com/playlist?list=PLXoynULbYuEDG2wBFSZ66b85EIspy3fy6">📼 Remix Singles</a>: <a href="https://www.youtube.com/watch?v=Iv25HAHaFDs&list=PLXoynULbYuEDG2wBFSZ66b85EIspy3fy6">Data Mutations with Form + action</a>, <a href="https://www.youtube.com/watch?v=w2i-9cYxSdc&list=PLXoynULbYuEDG2wBFSZ66b85EIspy3fy6">Multiple Forms and Single Button Mutations</a> and <a href="https://www.youtube.com/watch?v=bMLej7bg5Zo&list=PLXoynULbYuEDG2wBFSZ66b85EIspy3fy6">Clearing Inputs After Form Submissions</a></docs-success>

The `<Form>` component is a declarative way to perform data mutations: creating, updating, and deleting data. While it might be a mind-shift to think about these tasks as "navigation", it's how the web has handled mutations since before JavaScript was created!
Expand Down Expand Up @@ -92,6 +94,8 @@ When the `action` prop is omitted, `<Form>` and `<form>` will sometimes call dif
- `<form>` uses the current URL as the default which can lead to surprising results: forms inside parent routes will post to the child action if you're at the child's URL and the parents action when you're at the parent's URL. This means as the user navigates, the form's behavior changes.
- `<Form>` will always post to the route's action, independent of the URL. A form in a parent route will always post to the parent, even if you're at the child's URL.

<docs-info>For more information and usage, please refer to the [React Router `Form` docs][rr-form].</docs-info>

See also:

- [`useTransition`][usetransition]
Expand All @@ -103,3 +107,4 @@ See also:
[useactiondata]: ../hooks/use-action-data
[usesubmit]: ../hooks/use-submit
[http-verb]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
[rr-form]: https://reactrouter.com/components/form
1 change: 1 addition & 0 deletions docs/components/links.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: Links
toc: false
---

# `<Links />`
Expand Down
1 change: 1 addition & 0 deletions docs/components/live-reload.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: LiveReload
toc: false
---

# `<LiveReload />`
Expand Down
1 change: 1 addition & 0 deletions docs/components/meta.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: Meta
toc: false
---

# `<Meta />`
Expand Down
1 change: 1 addition & 0 deletions docs/components/nav-link.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: NavLink
toc: false
---

# `<NavLink>`
Expand Down
3 changes: 2 additions & 1 deletion docs/components/outlet.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
---
title: Outlet
toc: false
---

# `<Outlet>`

Re-export of [React Router Outlet][rr-outlet].
<docs-info>This component is simply a re-export of [React Router's `Outlet`][rr-outlet].</docs-info>

[rr-outlet]: https://reactrouter.com/components/outlet
1 change: 1 addition & 0 deletions docs/components/prefetch-page-links.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: PrefetchPageLinks
toc: false
---

# `<PrefetchPageLinks />`
Expand Down
1 change: 1 addition & 0 deletions docs/components/scripts.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: Scripts
toc: false
---

# `<Scripts />`
Expand Down
3 changes: 2 additions & 1 deletion docs/file-conventions/entry.client.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: entry.client
toc: false
---

# entry.client
Expand All @@ -19,4 +20,4 @@ hydrate(<RemixBrowser />, document);

This is the first piece of code that runs in the browser. As you can see, you have full control here. You can initialize client side libraries, setup things like `window.history.scrollRestoration`, etc.

[server-entry-module]: ./entry.server.tsx
[server-entry-module]: ./entry.server
1 change: 1 addition & 0 deletions docs/file-conventions/entry.server.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: entry.server
toc: false
---

# entry.server
Expand Down
1 change: 1 addition & 0 deletions docs/file-conventions/root.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: root
toc: false
---

# Root Route
Expand Down
31 changes: 26 additions & 5 deletions docs/file-conventions/route-files-v2.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,13 +185,14 @@ Note you typically want to add an index route when you add nested routes so that
Sometimes you want the URL to be nested but you don't want the automatic layout nesting. You can opt-out of nesting with a trailing underscore on the parent segment:

<!-- prettier-ignore -->
```markdown lines=[7]
```markdown lines=[8]
app/
├── routes/
│ ├── _index.tsx
│ ├── about.tsx
│ ├── concerts.$city.tsx
│ ├── concerts.trending.tsx
│ ├── concerts.tsx
│ └── concerts_.mine.tsx
└── root.tsx
```
Expand Down Expand Up @@ -279,7 +280,7 @@ app/
| `/` | `_index.tsx` |
| `/beef/and/cheese` | `$.tsx` |
| `/files` | `files.$.tsx` |
| `/files/talks/remix-conf_old.pdf` | `files/$.tsx` |
| `/files/talks/remix-conf_old.pdf` | `files.$.tsx` |
| `/files/talks/remix-conf_final.pdf` | `files.$.tsx` |
| `/files/talks/remix-conf-FINAL-MAY_2022.pdf` | `files.$.tsx` |

Expand All @@ -306,15 +307,18 @@ If you want one of the special characters Remix uses for these route conventions

## Folders for Organization

Routes can also be folders with a conventional `index.tsx` file inside defining the route module. The rest of the files in the folder will not become routes. This allows you to organize your code closer to the routes that use them instead of repeating the feature names across other folders.
Routes can also be folders with a conventional node module resolution `index.tsx` file inside defining the route module. The rest of the files in the folder will not become routes. This allows you to organize your code closer to the routes that use them instead of repeating the feature names across other folders.

<docs-info>The files inside a folder have no meaning for the route paths, the route path is completely defined by the folder name</docs-info>

Consider these routes:

```
routes/
_landing.about.tsx
_landing.index.tsx
_landing._index.tsx
_landing.tsx
app._index.tsx
app.projects.tsx
app.tsx
app_.projects.$id.roadmap.tsx
Expand All @@ -329,13 +333,16 @@ routes/
employee-profile-card.tsx
get-employee-data.server.tsx
team-photo.jpg
_landing.index/
_landing._index/
index.tsx
scroll-experience.tsx
_landing/
index.tsx
header.tsx
footer.tsx
app._index/
index.tsx
stats.tsx
app.projects/
index.tsx
project-card.tsx
Expand All @@ -352,6 +359,20 @@ routes/
contact-us.tsx
```

Note that `app/index.tsx` is _not_ the the "index route" for `app/`. It is the node module resolution "index module" for the folder `routes/app/`. The index route for `app/` is `app._index/index.tsx`. The only thing that contributes to the route path is the folder name.

```
# these are the same route:
routes/app.tsx
routes/app/index.tsx
# as are these
routes/app._index.tsx
route/app._index/index.tsx
```

In other words `_index` has meaning for Remix index routes, `index` has node module resolution meaning and creates index modules.

## Scaling

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:
Expand Down
6 changes: 4 additions & 2 deletions docs/file-conventions/routes-files.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ title: Route File Naming

# Route File Naming

<docs-info>The Route file naming convention is changing in v2, you can opt-in to the new convention today, [see the Route Convention v2 page][routeconvention-v2]</docs-info>

Setting up routes in Remix is as simple as creating files in your `app` directory. These are the conventions you should know to understand how routing in Remix works.

Please note that you can use either `.js`, `.jsx` or `.tsx` file extensions depending on whether or not you use TypeScript. We'll stick with `.tsx` in the examples to avoid duplication.
Expand Down Expand Up @@ -301,6 +299,10 @@ Because some characters have special meaning, you must use our escaping syntax i
Note, you could even do `app/routes/sitemap[.]xml.tsx` if you wanted to only wrap the part that needs to be escaped. It makes no difference. Choose the one you like best.
</docs-info>

## v2 Route Convention

The Route file naming convention is changing in v2 to make file organization simpler and make co-location of modules used by your routes simpler. You can opt-in to the new convention today, [see the Route Convention v2 page][routeconvention-v2] but you don't need to today, or ever if you don't want to.

[loader]: ../route/loader
[action]: ../route/action
[meta]: ../route/meta
Expand Down
2 changes: 1 addition & 1 deletion docs/guides/api-routes.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export async function loader({ request }: LoaderArgs) {

And then `useFetcher` along with Reach UI's combobox input:

```tsx [2,11,14,19,21,23]
```tsx lines=[2,11,14,19,21,23]
function CitySearchCombobox() {
const cities = useFetcher();

Expand Down
1 change: 1 addition & 0 deletions docs/guides/bff.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: Backend For Frontend
toc: false
---

# Backend For Your Frontend
Expand Down
6 changes: 3 additions & 3 deletions docs/guides/constraints.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ The most common scenario is initializing a third party API when your module is i

This ensures the library is only initialized if there is a `document`, meaning you're in the browser. We recommend `document` over `window` because server runtimes like Deno have a global `window` available.

```js [3]
```js lines=[3]
import firebase from "firebase/app";

if (typeof document !== "undefined") {
Expand All @@ -279,7 +279,7 @@ export { firebase };

This strategy defers initialization until the library is actually used:

```js [4]
```js lines=[4]
import { loadStripe } from "@stripe/stripe-js";

export async function redirectToStripeCheckout(sessionId) {
Expand Down Expand Up @@ -331,7 +331,7 @@ function useLocalStorage(key) {

You can fix this by moving the code into `useEffect`, which only runs in the browser.

```js [2,4-6]
```jsx lines=[2,4-6]
function useLocalStorage(key) {
const [state, setState] = useState(null);

Expand Down
16 changes: 9 additions & 7 deletions docs/guides/data-writes.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,9 @@ const [errors, project] = await createProject(formData);

If there are validation errors, we want to go back to the form and display them.

```tsx lines=[3,5-8]
```tsx lines=[1,5,7-10]
import { json, redirect } from "@remix-run/node"; // or cloudflare/deno

export const action = async ({ request }: ActionArgs) => {
const formData = await request.formData();
const [errors, project] = await createProject(formData);
Expand All @@ -227,7 +229,7 @@ Just like `useLoaderData` returns the values from the `loader`, `useActionData`

```tsx lines=[3,10,20,25-29,37,42-46]
import type { ActionArgs } from "@remix-run/node"; // or cloudflare/deno
import { redirect } from "@remix-run/node"; // or cloudflare/deno
import { json, redirect } from "@remix-run/node"; // or cloudflare/deno
import { useActionData } from "@remix-run/react";

export const action = async ({ request }: ActionArgs) => {
Expand Down Expand Up @@ -289,8 +291,8 @@ You can ship this code as-is. The browser will handle the pending UI and interru

Let's use progressive enhancement to make this UX a bit more fancy. By changing it from `<form>` to `<Form>`, Remix will emulate the browser behavior with `fetch`. It will also give you access to the pending form data so you can build pending UI.

```tsx [2, 11]
import { redirect } from "@remix-run/node"; // or cloudflare/deno
```tsx lines=[2,11]
import { json, redirect } from "@remix-run/node"; // or cloudflare/deno
import { useActionData, Form } from "@remix-run/react";

// ...
Expand All @@ -313,8 +315,8 @@ If you don't have the time or drive to do the rest of the job here, use `<Form r

Now let's add some pending UI so the user has a clue something happened when they submit. There's a hook called `useTransition`. When there is a pending form submission, Remix will give you the serialized version of the form as a <a href="https://developer.mozilla.org/en-US/docs/Web/API/FormData">`FormData`</a> object. You'll be most interested in the <a href="https://developer.mozilla.org/en-US/docs/Web/API/FormData/get">`formData.get()`</a> method.

```tsx [5, 13, 19, 65-67]
import { redirect } from "@remix-run/node"; // or cloudflare/deno
```tsx lines=[5,13,19,65-67]
import { json, redirect } from "@remix-run/node"; // or cloudflare/deno
import {
useActionData,
Form,
Expand Down Expand Up @@ -426,7 +428,7 @@ function ValidationMessage({ error, isSubmitting }) {

Now we can wrap our old error messages in this new fancy component, and even turn the borders of our fields red that have errors:

```tsx [21-24, 31-34, 44-48, 53-56]
```tsx lines=[21-24,31-34,44-48,53-56]
export default function NewProject() {
const transition = useTransition();
const actionData = useActionData<typeof action>();
Expand Down
Loading

0 comments on commit b0f1985

Please sign in to comment.