How to optimize your Storyblok app
Tags: webdev, storyblok, react, javascript
Published: 2023-08-15 15:56:42

If you are using @storyblokcom with NextJS, and following [the official guides from Storyblok](https://www.storyblok.com/tp/add-a-headless-cms-to-next-js-in-5-minutes), you know that the usual way to start the project is:

1. Create a NextJS project using `create-next-app`
2. Install the necessary dependencies to integrate with Storyblok.
3. Create your Storyblok components.
4. Initialize the NextJS - Storyblok connection by adding the following code to your `_app.jsx`.

```js
...
 
import { storyblokInit, apiPlugin } from "@storyblok/react";
import Feature from "../components/Feature";
import Grid from "../components/Grid";
import Page from "../components/Page";
import Teaser from "../components/Teaser";
 
const components = {
  feature: Feature,
  grid: Grid,
  teaser: Teaser,
  page: Page,
};
 
storyblokInit({
  accessToken: "your-preview-token",
  use: [apiPlugin],
  components,
});
 
...
```

##The problem:
**You are loading all of your components on each page load!**

This is because the contents of `_app.jsx` get executed on every page. So all the JavaScript that is imported in the `_app.jsx` file, gets bundled and sent to the client on every page load.

Since the official guide recommends importing **all** of your components in the `_app.jsx` file, this means that **all** your component code get loaded on every page. Even if that page is completely static and doesn't use any StoryBlok components at all!

I ended up creating [a Github issue](https://github.com/storyblok/storyblok-react/issues/595), and [implementing this feature via a PR](https://github.com/storyblok/storyblok-react/pull/598), on the official [@storyblok/react](https://github.com/storyblok/storyblok-react) Github repo. I was a bit hesitent about contributing, but the good folks at the `@storyblok/react` repo were very kind and accepting of it, so a big thanks to them!

## How to load only the stuff you need
Instead of loading all your components in the `_app.jsx` file, just initialize the connection, and remove any component imports you have, so it looks more like this:

```js
...
 
import { storyblokInit, apiPlugin } from "@storyblok/react";
 
storyblokInit({
  accessToken: "your-preview-token",
  use: [apiPlugin],
});
 
...
```

Then, in your page components, use the new `setComponents` method, to set only the components you need on that page. So it would look something like this:

```js
...
 
import { getStoryblokApi, StoryblokComponent, setComponents } from "@storyblok/react"
import Feature from "../components/Feature";
import Grid from "../components/Grid";
import Page from "../components/Page";
import Teaser from "../components/Teaser";
 
export default function Home(props) {
    const story = props.story
    setComponents({
      feature: Feature,
      grid: Grid,
      teaser: Teaser,
      page: Page,
    })
   
    return (
      <div className={styles.container}>
        <Head>
          <title>Create Next App</title>
          <link rel="icon" href="/favicon.ico" />
        </Head>
   
        <header>
          <h1>
            { story ? story.name : 'My Site' }
          </h1>
        </header>
   
         <StoryblokComponent blok={story.content} />
      </div>
    )
  }
 
...
```

That's it!

Now, when NextJS builds your page, it will only include the components imported directly on that page and reduce your JS bundle size per page, improving your SEO and speeding up your page load times.