Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cherry-pick v2 docs from dev into release-next #7408

Merged
merged 29 commits into from
Sep 13, 2023
Merged
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
7ce2354
Add docs on error santization (#7315)
brophdawg11 Aug 31, 2023
5967851
chore: format
remix-run-bot Aug 31, 2023
df305ce
docs: form
ryanflorence Aug 29, 2023
49deef4
docs: link docs
ryanflorence Aug 31, 2023
60064f1
chore: format
remix-run-bot Aug 31, 2023
78add14
docs: NavLink
ryanflorence Aug 31, 2023
0396288
chore: format
remix-run-bot Aug 31, 2023
c5dcff2
docs: outlet
ryanflorence Aug 31, 2023
267b339
docs: Scripts
ryanflorence Aug 31, 2023
9d38b94
docs: scroll restoration
ryanflorence Sep 1, 2023
f45397d
docs: useActionData
ryanflorence Sep 1, 2023
550ee66
chore: format
remix-run-bot Sep 1, 2023
ed9882a
docs stuff
ryanflorence Sep 3, 2023
888c9a8
chore: format
remix-run-bot Sep 3, 2023
7edad5b
docs: more API docs updates
ryanflorence Sep 5, 2023
5ac0095
chore: format
remix-run-bot Sep 5, 2023
4568185
docs: useFetchers
ryanflorence Sep 5, 2023
61c913e
chore: format
remix-run-bot Sep 5, 2023
b92ddde
docs: useFormAction
ryanflorence Sep 5, 2023
7c859c1
docs: useHref
ryanflorence Sep 5, 2023
825dae8
docs: useLoaderData
ryanflorence Sep 5, 2023
a7635f3
chore: format
remix-run-bot Sep 5, 2023
03b2a38
docs: useLocation
ryanflorence Sep 5, 2023
aa6d476
chore: format
remix-run-bot Sep 5, 2023
d31cfeb
docs: moving stuff around
ryanflorence Sep 13, 2023
af495a1
docs: fix links to moved files
ryanflorence Sep 13, 2023
ba3906c
docs: nothin
ryanflorence Sep 13, 2023
cb480d9
docs: update main index page
ryanflorence Sep 13, 2023
9cc2966
Change docs cards to point to main
brophdawg11 Sep 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
docs: link docs
  • Loading branch information
ryanflorence authored and brophdawg11 committed Sep 13, 2023
commit 49deef498c90c5aa927cfee7fc89eec5e92eed46
135 changes: 116 additions & 19 deletions docs/components/link.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,17 @@ title: Link

# `<Link>`

This component renders an anchor tag and is the primary way the user will navigate around your website. Anywhere you would have used `<a href="...">` you should now use `<Link to="..."/>` to get all the performance benefits of client-side routing in Remix.
A `<a href>` wrapper to enable navigation with client-side routing.

```tsx
import { Link } from "@remix-run/react";

export default function GlobalNav() {
return (
<nav>
<Link to="/dashboard">Dashboard</Link>{" "}
<Link to="/account">Account</Link>{" "}
<Link to="/support">Support</Link>
</nav>
);
}
<Link to="/dashboard">Dashboard</Link>;
```

## `prefetch`

In the effort to remove all loading states from your UI, `Link` can automatically prefetch all the resources the next page needs: JavaScript modules, stylesheets, and data. This prop controls if and when that happens.
Defines the data and module prefetching behavior for the link.

```tsx
<>
Expand All @@ -34,17 +26,122 @@ 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"`, `<link rel="prefetch">` elements will be inserted on hover/focus and removed if the `<Link>` 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.
- **"viewport"** - Fetches while the link is in the viewport
- **none** - default, no prefetching
- **intent** - prefetches when the user hovers or focuses the link
- **render** - prefetches when the link renders
- **viewport** - prefetches when the link is in the viewport, very useful for mobile

Prefetching is done with HTML `<link rel="prefetch">` tags. They are inserted after the link.

```tsx
<nav>
<a href="..." />
<a href="..." />
<link rel="prefetch" /> {/* might conditionally render */}
</nav>
```

Because of this, if you are using `nav :last-child` you will need to use `nav :last-of-type` so the styles don't conditionally fall off your last link (and any other similar selectors).

## `preventScrollReset`

If you are using [`<ScrollRestoration>`](./scroll-restoration), this lets you prevent the scroll position from being reset to the top of the window when the link is clicked.

```tsx
<Link to="?tab=one" preventScrollReset />
```

This does not prevent the scroll position from being restored when the user comes back to the location with the back/forward buttons, it just prevents the reset when the user clicks the link.

<details>
<summary>Discussion</summary>

An example when you might want this behavior is a list of tabs that manipulate the url search params that aren't at the top of the page. You wouldn't want the scroll position to jump up to the top because it might scroll the toggled content out of the viewport!

```
┌─────────────────────────┐
│ ├──┐
│ │ │
│ │ │ scrolled
│ │ │ out of view
│ │ │
│ │ ◄┘
┌─┴─────────────────────────┴─┐
│ ├─┐
│ │ │ viewport
│ ┌─────────────────────┐ │ │
│ │ tab tab tab │ │ │
│ ├─────────────────────┤ │ │
│ │ │ │ │
│ │ │ │ │
│ │ content │ │ │
│ │ │ │ │
│ │ │ │ │
│ └─────────────────────┘ │ │
│ │◄┘
└─────────────────────────────┘

```

</details>

## `relative`

Defines the relative path behavior for the link.

```tsx
<Link to=".." />; // default: "route"
<Link relative="route" />;
<Link relative="path" />;
```

- **route** - default, relative to the route hierarchy so `..` will remove all URL segments of the current route pattern
- **path** - relative to the path so `..` will remove one URL segment

## `reloadDocument`

Will use document navigation instead of client side routing when the link is clicked, the browser will handle the transition normally (as if it were an `<a href>`).

```tsx
<Link to="/logout" reloadDocument />
```

## `replace`

The `replace` prop will replace the current entry in the history stack instead of pushing a new one onto it.

<docs-error>You may need to use the <code>:last-of-type</code> selector instead of <code>:last-child</code> when styling child elements inside of your links</docs-error>
```tsx
<Link replace />
```

Remix uses the browser's cache for prefetching with HTML `<link rel="prefetch"/>` tags, which provides a lot of subtle benefits (like respecting HTTP cache headers, doing the work in browser idle time, using a different thread than your app, etc.) but the implementation might mess with your CSS since the link tags are rendered inside of your anchor tag. This means `a *:last-child {}` style selectors won't work. You'll need to change them to `a *:last-of-type {}` and you should be good. We will eventually get rid of this limitation.
```
# with a history stack like this
A -> B

## React Router `<Link/>`
# normal link click pushes a new entry
A -> B -> C

# but with `replace`, B is replaced by C
A -> C
```

## `state`

Adds persistent client side routing state to the next location.

```tsx
<Link to="/somewhere/else" state={{ some: "value" }} />
```

The location state is accessed from the `location`.

```ts
function SomeComp() {
const location = useLocation();
location.state; // { some: "value" }
}
```

This component is a wrapper around [React Router `<Link/>`][rr-link]. It has the same API except for Remix's `prefetch` addition. For more information and advanced usage, refer to the [React Router docs][rr-link].
This state is inaccessible on the server as it is implemented on top of [`history.state`](https://developer.mozilla.org/en-US/docs/Web/API/History/state).

[rr-link]: https://reactrouter.com/en/main/components/link