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

chore(docs): Move loadable-components instructions #35116

Merged
merged 3 commits into from
Mar 23, 2022
Merged
Show file tree
Hide file tree
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
62 changes: 30 additions & 32 deletions docs/docs/using-client-side-only-packages.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ On occasion, you may need to use a function or library that only works client-si
You'll need to use one of the workarounds outlined below if your project fails to compile with `gatsby develop` or `gatsby build` with an error like:

```shell
Reference error: Window is not Defined
Reference error: window is not defined
```

## Workaround 1: Use a different library or approach
Expand All @@ -21,7 +21,7 @@ In the component where you need it, load the package via CDN using a [`<script /
To embed your script, you can:

- Include it in a custom component as needed using [`react-helmet`](https://github.com/nfl/react-helmet).
- Add the script tag directly in your base HTML using Gatsby's [html.js](/docs/custom-html/)
- Add the script tag directly by using Gatsby's [`setHeadComponents`](/docs/reference/config-files/gatsby-ssr/#onRenderBody) in the `onRenderBody` API in `gatsby-ssr`.

You should then follow React's guidelines for [Integrating with DOM Manipulation Plugins](https://reactjs.org/docs/integrating-with-other-libraries.html#integrating-with-dom-manipulation-plugins), using the methods available in the [React Component Lifecycle](https://reactjs.org/docs/react-component.html#the-component-lifecycle) to interact with the library you're using.

Expand Down Expand Up @@ -50,16 +50,41 @@ class MyComponent extends Component {
}
```

## Workaround 3: Load client-side dependent components with loadable-components
## Workaround 3: Use React.lazy and Suspense on client-side only

React.lazy and Suspense are not ready for server-side rendering, but they can be used by checking that the code is executed only on the client. While this solution is inferior to `loadable-components`, that works both on server side and client, it still provides an alternative for dealing with client-side only packages, without an added dependency. Remember that the following code could break if executed without the `isSSR` guard.

```jsx
import React from "react"

const ClientSideOnlyLazy = React.lazy(() =>
import("../components/ClientSideOnly")
)
const MyPage = () => {
const isSSR = typeof window === "undefined"

return (
<>
{!isSSR && (
<React.Suspense fallback={<div />}>
<ClientSideOnlyLazy />
</React.Suspense>
)}
</>
)
}
```

## Workaround 4: Load client-side dependent components with loadable-components

Install [loadable-components](https://github.com/smooth-code/loadable-components) and use it as a wrapper for a component that wants to use a client-side only package.

```shell
npm install @loadable/component
# or use yarn
yarn add @loadable/component
```

And in your component:

```jsx
import React, { Component } from "react"
import PropTypes from "prop-types"
Expand All @@ -80,33 +105,6 @@ const LoadableBuyButton = Loadable(() => import("./ShopifyBuyButton"))
export default LoadableBuyButton
```

## Workaround 4: Use React.lazy and Suspense on client-side only

React.lazy and Suspense are still not ready for server-side rendering, but they can still be used by checking that the code is executed only on the client.
While this solution is inferior to `loadable-components`, that works both on server side and client, it still provides an alternative for dealing with client-side only packages, without an added dependency.
Remember that the following code could break if executed without the `isSSR` guard.

```jsx
import React from "react"

const ClientSideOnlyLazy = React.lazy(() =>
import("../components/ClientSideOnly")
)
const MyPage = () => {
const isSSR = typeof window === "undefined"

return (
<>
{!isSSR && (
<React.Suspense fallback={<div />}>
<ClientSideOnlyLazy />
</React.Suspense>
)}
</>
)
}
```

> **Note:** There are other potential workarounds than those listed here. If you've had success with another method, check out the [contributing docs](/contributing/docs-contributions/) and add yours!

If all else fails, you may also want to check out the documentation on [Debugging HTML Builds](/docs/debugging-html-builds/).
2 changes: 1 addition & 1 deletion packages/gatsby/src/utils/api-node-docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ export const preprocessSource = true
export const onCreateBabelConfig = true

/**
* Let plugins extend/mutate the site's webpack configuration.
* Let plugins extend/mutate the site's webpack configuration. This method can be used by any Gatsby site, app, or plugin, not just plugins.
*
* See also the documentation for [`setWebpackConfig`](/docs/actions/#setWebpackConfig).
*
Expand Down