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

docs: add videos for Gatsby Link + rewrite for flow #11700

Merged
merged 3 commits into from
Feb 12, 2019
Merged
Changes from all commits
Commits
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
287 changes: 189 additions & 98 deletions docs/docs/gatsby-link.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,81 @@ Gatsby's `<Link>` component enables linking to internal pages as well as a power

The component is a wrapper around [@reach/router's Link component](https://reach.tech/router/api/Link) that adds useful enhancements specific to Gatsby. All props are passed through to @reach/router's `Link` component.

## How to use
## How to use Gatsby Link

In JavaScript:
<iframe title="Screencast on egghead of how to use a Gatsby Link" class="egghead-video" width=600 height=348 src="https://egghead.io/lessons/egghead-why-and-how-to-use-gatsby-s-link-component/embed" />

Video hosted on [egghead.io][egghead].

### Replace `a` tags with the `Link` tag for local links

In any situation where you want to link between pages on the same site, use the `Link` component instead of an `a` tag.

```jsx
import React from "react"
// highlight-next-line
import { Link } from "gatsby"

class Page extends React.Component {
render() {
return (
<div>
<Link
to="/another-page/"
activeStyle={{
color: "red",
}}
ref={el => {
this.myLink = el
}}
state={{
pleasant: "reasonably",
}}
>
Another page
</Link>
</div>
)
}
}
const Page = () => (
<div>
<p>
{/* highlight-next-line */}
Check out my <Link to="/blog">blog</Link>!
</p>
<p>
{/* Note that external links still use `a` tags. */}
Follow me on <a href="https://twitter.com/gatsbyjs">Twitter</a>!
</p>
</div>
)
```

### Partial Link matching
### Add custom styles for the currently active link
jlengstorf marked this conversation as resolved.
Show resolved Hide resolved

<iframe title="Screencast on egghead of how to style the currently active link in Gatsby." class="egghead-video" width=600 height=348 src="https://egghead.io/lessons/egghead-add-custom-styles-for-the-active-link-using-gatsby-s-link-component/embed" />

Video hosted on [egghead.io][egghead].

It’s often a good idea to show which page is currently being viewed by visually changing the link matching the current page.

`Link` provides two options for adding styles to the active link:

- `activeStyle` — a style object that will only be applied when the current item is active
- `activeClassName` — a class name that will only be added to the `Link` when the current item is active

For example, to turn the active link red, either of the following approaches is valid:

```jsx
import React from "react"
import { Link } from "gatsby"

const SiteNavigation = () => (
<nav>
<Link
to="/"
{/* highlight-start */}
{/* This assumes the `active` class is defined in your CSS */}
activeClassName="active"
{/* highlight-end */}
>
Home
</Link>
<Link
to="/about/"
{/* highlight-next-line */}
activeStyle={{ color: red }}
>
About
</Link>
</nav>
)
```

### Show active styles for partially matched and parent links

<iframe title="Screencast on egghead of how to style partially matched links in Gatsby." class="egghead-video" width=600 height=348 src="https://egghead.io/lessons/egghead-customize-styles-for-partially-matched-urls-with-gatsby-s-link-component/embed" />

Video hosted on [egghead.io][egghead].

The `activeStyle` or `activeClassName` prop are only set on a `<Link>` component if the current URL matches its `to` prop _exactly_. Sometimes, we may want to style a `<Link>` as active even if it partially matches the current URL. For example:

Expand All @@ -52,131 +94,178 @@ In instances like these, we can use [@reach/router's](https://reach.tech/router/
```jsx
import React from "react"
import { Link } from "gatsby"
// This link will get the active class when it partially matches the current URL
const PartialNavLink = props => (

const PartialNavLink = () => (
<Link
getProps={({ isPartiallyCurrent }) => {
return isPartiallyCurrent ? { className: "active" } : null
}}
/>
to="/blog/"
{/* highlight-start */}
getProps={({ isPartiallyCurrent }) =>
isPartiallyCurrent ? { className: "active" } : null
}
{/* highlight-end */}
>
Blog
</Link>
)
```

Check out this [codesandbox](https://codesandbox.io/s/p92vm09m37) for a working example!

### Passing props to Link targets
### Pass state as props to the linked page

<iframe title="Screencast on egghead of how to pass state as props using Gatsby’s Link component." class="egghead-video" width=600 height=348 src="https://egghead.io/lessons/egghead-include-information-about-state-in-navigation-with-gatsby-s-link-component/embed" />

Video hosted on [egghead.io][egghead].

Sometimes you'll want to pass data from the source page to the linked page. You can do this by passing a `state` prop to the `Link` component or on a call to the `navigate` function. The linked page will have a `location` prop containing a nested `state` object structure containing the passed data.

```jsx
const NewsFeed = () => (
const PhotoFeedItem = ({ id }) => (
<div>
<Link to="photos/123" state={{ fromFeed: true }} />
{/* (skip the feed item markup for brevity) */}
<Link
to={`/photos/${id}`}
{/* highlight-next-line */}
state={{ fromFeed: true }}
>
View Photo
</Link>
</div>
)

// highlight-start
const Photo = ({ location, photoId }) => {
if (location.state.fromFeed) {
// highlight-end
return <FromFeedPhoto id={photoId} />
} else {
return <Photo id={photoId} />
}
}
```

### Using navigate()
### Replace history to change “back” button behavior

<iframe title="Screencast on egghead of how to replace history on navigation." class="egghead-video" width=600 height=348 src="https://egghead.io/lessons/egghead-replace-navigation-history-items-with-gatsby-s-link-component/embed" />

Sometimes you need to navigate to pages programatically:
Video hosted on [egghead.io][egghead].

#### Replacing history entry
There are a few cases where it might make sense to modify the “back” button’s behavior. For example, if you build a page where you choose something, then see an “are you sure?” page to make sure it’s what you really wanted, and finally see a confirmation page, it may be desirable to skip the “are you sure?” page if the “back” button is clicked.

You can pass boolean `replace` property to replace previous history entry.
Therefore clicking the back button after navigation to such Link would redirect
to page before, _skipping_ the page the link was on.
In those cases, use the `replace` prop to replace the current URL in history with the target of the `Link`.

```jsx
import { navigate } from "gatsby"
import React from "react"
import { Link } from "gatsby"

render () {
return (
<div onClick={ () => navigate('/example')} role="link" tabIndex="0" onKeyUp={this.handleKeyUp}>
<p>Example</p>
</div>
)
}
const AreYouSureLink = () => (
<Link
to="/confirmation/"
{/* highlight-next-line */}
replace
>
Yes, I’m sure
</Link>
)
```

The `navigate` function accepts two parameters (see following sections):
## How to use the `navigate` helper function

<iframe title="Screencast on egghead of how to navigate programmatically in Gatsby." class="egghead-video" width=600 height=348 src="https://egghead.io/lessons/egghead-navigate-to-a-new-page-programmatically-in-gatsby/embed" />

- a string representing the destination
- optional settings object. The settings object can include two optional properties: `state (object)`, and `replace (bool, default false)`.
Video hosted on [egghead.io][egghead].

_Note that `navigate` was previously named `navigateTo`. `navigateTo` is deprecated in Gatsby v2 and will be removed in the next major release_
Sometimes you need to navigate to pages programatically, such as during form submissions. In these cases, `Link` won’t work.

#### Pushing versus Replacing history entry
_**Note:** `navigate` was previously named `navigateTo`. `navigateTo` is deprecated in Gatsby v2 and will be removed in the next major release._

By default, both `<Link>` and `navigate` will _push_ a new entry to the history stack.
Instead, Gatsby exports a `navigate` helper function that accepts `to` and `options` arguments.

This can be changed by passing a `replace` prop to the Link component, or by passing `replace: true` to the `navigate` settings object.
| Argument | Required | Description |
| ----------------- | -------- | ------------------------------------------------------------------------------------------------ |
| `to` | yes | The page to navigate to (e.g. `/blog/`). |
| `options.state` | no | An object. Values passed here will be available in `locations.state` in the target page’s props. |
| `options.replace` | no | A boolean value. If true, replaces the current URL in history. |

When replace is enabled, clicking the browser back button will return the user to the page _preceeding the page from which they navigated_.
By default, `navigate` operates the same way as a clicked `Link` component.

```jsx
import { Link } from 'gatsby'
import React from "react"
import { navigate } from "gatsby" // highlight-line

render () {
return (
<Link
to="/another-page/"
replace
>
Go and prevent back to bring you back here
</Link>
)
}
const Form = () => (
<form
onSubmit={event => {
event.preventDefault()

// TODO: do something with form values
// highlight-next-line
navigate("/form-submitted/")
}}
>
{/* (skip form inputs for brevity) */}
</form>
)
```

Using `replace` also won't scroll the page after navigation.
### Add state to programmatic navigation

### Passing state through Link and Navigate
To include state information, add an `options` object and include a `state` prop with the desired state.

You can pass state to pages when you navigate, such as:
```jsx
import React from "react"
import { navigate } from "gatsby"

```javascript
navigate(`/a-path/`, { state: { pleasant: `reasonably` }}
const Form = () => (
<form
onSubmit={event => {
event.preventDefault()

// Implementation of this function is an exercise for the reader.
const formValues = getFormValues()

navigate(
"/form-submitted/",
// highlight-start
{
state: { formValues },
}
// highlight-end
)
}}
>
{/* (skip form inputs for brevity) */}
</form>
)
```

You can also pass state to pages when you use `Link`:
### Replace history during programmatic navigation

If the navigation should replace history instead of pushing a new entry into the navigation history, add the `replace` prop with a value of `true` to the `options` argument of `navigate`.

```jsx
<Link
to="/another-page/"
activeStyle={{
color: "red",
}}
state={{
pleasant: "reasonably",
}}
>
```
import React from "react"
import { navigate } from "gatsby"

This is accessible from the `location` object on the new page:
const Form = () => (
<form
onSubmit={event => {
event.preventDefault()

```javascript
componentDidMount() {
const pleasant = this.props.location.state.pleasant
this.setState({
pleasant: pleasant
})
}
// TODO: do something with form values
navigate(
"/form-submitted/",
// highlight-next-line
{ replace: true }
)
}}
>
{/* (skip form inputs for brevity) */}
</form>
)
```

### Styling

You can set the `activeStyle` or `activeClassName` prop to add styling
attributes to the rendered element when it matches the current URL.

### Prefixed paths helper
## Add the path prefix to paths using `withPrefix`

It is common to host sites in a sub-directory of a site. Gatsby lets you [set
the path prefix for your site](/docs/path-prefix/). After doing so, Gatsby's `<Link>` component will automatically handle constructing the correct URL in development and production.
Expand All @@ -198,7 +287,7 @@ const IndexLayout = ({ children, location }) => {
}
```

## Use `<Link>` only for internal links!
## Reminder: use `<Link>` only for internal links!

This component is intended _only_ for links to pages handled by Gatsby. For links to pages on other domains or pages on the same domain not handled by the current Gatsby site, use the normal `<a>` element.

Expand Down Expand Up @@ -265,3 +354,5 @@ You can similarly check for file downloads:
)
}
```

[egghead]: https://egghead.io/playlists/use-gatsby-s-link-component-to-improve-site-performance-and-simplify-site-development-7ed3ddfe