+
+## đ Usage
+
+> If you are first-time user of the Storyblok, read the [Getting Started](https://www.storyblok.com/docs/guide/getting-started?utm_source=github.com&utm_medium=readme&utm_campaign=gatsby-source-storyblok) guide to get a project ready in less than 5 minutes.
+
+### Installation
+
+Install `gatsby-source-storyblok`:
+
+```bash
+npm install gatsby-source-storyblok
+// yarn add gatsby-source-storyblok
```
-## Usage
+### Initialization
-1. You need to declare the plugin use and its options in `gatsby-config.js`
+Register the plugin on your application and add the [access token](https://www.storyblok.com/docs/api/content-delivery#topics/authentication?utm_source=github.com&utm_medium=readme&utm_campaign=gatsby-source-storyblok) of your Storyblok space. You can also add the `apiPlugin` in case that you want to use the Storyblok API Client:
+
+> You need to declare the plugin use and its options in `gatsby-config.js`
```JavaScript
module.exports = {
@@ -28,11 +62,233 @@ module.exports = {
}
```
-### With Gatsby's image
+`src/components/layout.js`
+
+```JavaScript
+import configuration from '../../gatsby-config'
+
+const sbConfig = configuration.plugins.find((item) => item.resolve === 'gatsby-source-storyblok')
+
+storyblokInit({
+ accessToken: sbConfig.options.accessToken,
+ // bridge: false,
+ // apiOptions: { },
+ use: [apiPlugin],
+ components: {
+ teaser: Teaser,
+ grid: Grid,
+ feature: Feature
+ }
+});
+```
+
+> Add all your components to the components object in the `storyblokInit` function.
+
+That's it! All the features are enabled for you: the _Api Client_ for interacting with [Storyblok CDN API](https://www.storyblok.com/docs/api/content-delivery#topics/introduction?utm_source=github.com&utm_medium=readme&utm_campaign=gatsby-source-storyblok), and _Storyblok Bridge_ for [real-time visual editing experience](https://www.storyblok.com/docs/guide/essentials/visual-editor?utm_source=github.com&utm_medium=readme&utm_campaign=gatsby-source-storyblok).
+
+> You can enable/disable some of these features if you don't need them, so you save some KB. Please read the "Features and API" section
+
+### Getting Started
+
+`gatsby-source-storyblok` does three actions when you initialize it:
+
+- Provides a `useStoryblokState` custom hook in your app, that parses story content JSON into the object.
+- Loads [Storyblok Bridge](https://www.storyblok.com/docs/Guides/storyblok-latest-js?utm_source=github.com&utm_medium=readme&utm_campaign=gatsby-source-storyblok) for real-time visual updates.
+- Provides a `storyblokEditable` function to link editable components to the Storyblok Visual Editor.
+
+#### 1. Fetching Content
+
+Query data from GraphQL:
+
+`src/pages/index.js`
+
+```js
+import { useStoryblokState } from "gatsby-source-storyblok"
+
+import Layout from "../components/layout"
+
+const IndexPage = ({ data }) => {
+ let story = data.storyblokEntry
+ story = useStoryblokState(story)
+
+ return (
+
+
+
{story.name}
+
+
+ )
+}
+
+export default IndexPage
+
+export const query = graphql`
+ query HomeQuery {
+ storyblokEntry(full_slug: { eq: "home" }) {
+ name
+ full_slug
+ }
+ }
+`
+```
+
+> Note: if you don't use `apiPlugin`, you can use your prefered method or function to fetch your data.
+
+#### 2. Listen to Storyblok Visual Editor events
+
+Use `useStoryblok` to get the new story every time is triggered a `change` event from the Visual Editor. You need to pass the `originalStory` as a first param. `bridgeOptions` (second param) is an optional param if you want to set the options for bridge by yourself:
+
+```js
+import { StoryblokComponent, useStoryblokState } from "gatsby-source-storyblok"
+
+import Layout from "../components/layout"
+
+const IndexPage = ({ data }) => {
+ let story = data.storyblokEntry
+ story = useStoryblokState(story)
+
+ const components = story.content.body.map(blok => ())
+
+ return (
+
+
+
{story.name}
+ {components}
+
+
+ )
+}
+
+export default IndexPage
+
+export const query = graphql`
+ query HomeQuery {
+ storyblokEntry(full_slug: { eq: "home" }) {
+ content
+ name
+ full_slug
+ internalId
+ }
+ }
+`
+```
+
+You can pass Bridge options as a third parameter as well:
+
+```js
+useStoryblok(story.internalId, (newStory) => setStory(newStory), {
+ resolveRelations: ["Article.author"],
+});
+```
+
+#### 3. Link your components to Storyblok Visual Editor
+
+For every component you've defined in your Storyblok space, call the `storyblokEditable` function with the blok content:
+
+```js
+import { storyblokEditable } from "gatsby-source-storyblok";
+
+const Feature = ({ blok }) => {
+ return (
+
+
+
{blok.name}
+
{blok.description}
+
+
+ );
+};
+
+export default Feature;
+```
+
+Where `blok` is the actual blok data coming from [Storblok's Content Delivery API](https://www.storyblok.com/docs/api/content-delivery?utm_source=github.com&utm_medium=readme&utm_campaign=gatsby-source-storyblok).
+
+As an example, you can check in our [Gatsby.js example demo]() how we use APIs provided from React SDK to combine with Gatsby.js projects.
+
+```js
+import { StoryblokComponent, storyblokEditable, useStoryblokState } from "gatsby-source-storyblok"
+
+import Layout from "../components/layout"
+
+const IndexPage = ({ data }) => {
+ let story = data.storyblokEntry
+ story = useStoryblokState(story)
+
+ const components = story.content.body.map(blok => ())
+
+ return (
+
+
+ {components}
+
+
+ )
+}
+
+export default IndexPage
+
+export const query = graphql`
+ query HomeQuery {
+ storyblokEntry(full_slug: { eq: "home" }) {
+ content
+ name
+ full_slug
+ internalId
+ }
+ }
+`
+```
+
+### Features and API
+
+You can **choose the features to use** when you initialize the plugin. In that way, you can improve Web Performance by optimizing your page load and save some bytes.
+
+#### Storyblok API
+
+You can use an `apiOptions` object. This is passed down to the [storyblok-js-client config object](https://github.com/storyblok/storyblok-js-client#class-storyblok):
+
+```js
+storyblokInit({
+ accessToken: "YOUR_ACCESS_TOKEN",
+ apiOptions: {
+ // storyblok-js-client config object
+ cache: { type: "memory" },
+ },
+ use: [apiPlugin],
+ components: {
+ teaser: Teaser,
+ grid: Grid,
+ feature: Feature,
+ },
+});
+```
+
+If you prefer to use your own fetch method, just remove the `apiPlugin` and `storyblok-js-client` won't be added to your application.
+
+```js
+storyblokInit({});
+```
+
+#### Storyblok Bridge
+
+If you don't use `useStoryblokBridge`, you still have access to the raw `window.StoryblokBridge`:
+
+```js
+const sbBridge = new window.StoryblokBridge(options);
+
+sbBridge.on(["input", "published", "change"], (event) => {
+ // ...
+});
+```
+
+### Gatsby feature references
+
+#### With Gatsby's image
You need to set the `localAssets` option to `true`. Here is an example of the usage:
-```JavaScript
+```js
import { graphql } from "gatsby"
import { GatsbyImage, getImage } from "gatsby-plugin-image"
@@ -63,28 +319,31 @@ export const pageQuery = graphql`
`
```
-### With Gatsby's createPages
+#### With Gatsby's createPages
For more info regarding `createPages` see the Gatsby docs: [docs/reference/config-files/gatsby-node/#createPages](https://www.gatsbyjs.com/docs/reference/config-files/gatsby-node/#createPages)
2a. You need to create a [template](https://www.gatsbyjs.org/docs/programmatically-create-pages-from-data/#specifying-a-template) file to get the data from GraphQL
```js
-import React from 'react'
-import { graphql } from 'gatsby'
+import { useStoryblokState } from "gatsby-source-storyblok"
+import Layout from "../components/layout"
export default function StoryblokEntry ({ data }) {
- let story = data.storyblokEntry
+ const story = data.storyblokEntry
+ story = useStoryblokState(story)
return (
-
{story.name}
+
+
{story.name}
+
)
}
export const query = graphql`
query($slug: String!) {
- storyblokEntry(slug: { eq: $slug }) {
- id
+ storyblokEntry(full_slug: { eq: $full_slug }) {
+ internalId
name
full_slug
}
@@ -106,7 +365,7 @@ exports.createPages = async ({ graphql, actions }) => {
allStoryblokEntry {
edges {
node {
- id
+ internalId
full_slug
}
}
@@ -131,7 +390,7 @@ exports.createPages = async ({ graphql, actions }) => {
```
-### With Gatsby's File System Routes API
+#### With Gatsby's File System Routes API
For more info regarding The File System Routes API see the Gatsby docs: [docs/reference/routing/file-system-route-api/](https://www.gatsbyjs.com/docs/reference/routing/file-system-route-api/)
@@ -141,72 +400,41 @@ For more info regarding The File System Routes API see the Gatsby docs: [docs/re
```
|-- src
|-- pages
- |-- {storyblokEntry.slug}.js
+ |-- {storyblokEntry.full_slug}.js
```
3b. Gatsby will use ths page template for each `storyblokEntry`
```js
-import React from 'react'
-import { graphql } from 'gatsby'
-
-export default function StoryblokEntry({ data }) {
- let story = data.storyblokEntry
-
- return
{story.name}
-}
-
-export const query = graphql`
- query ($full_slug: String!) {
- storyblokEntry(full_slug: { eq: $full_slug }) {
- id
- name
- full_slug
- }
- }
-`
-```
+import { useStoryblokState } from "gatsby-source-storyblok"
+import Layout from "../components/layout"
-## Rendering Storyblok content
-
-To source Storyblok's content add `content` to your GraphQL query. By importing `DynamicComponent`, you can render components dynamically. `sbEditable` function lets you to make your components editable in [storyblok.com](https://www.storyblok.com/)
-
-For more info regarding `sbEditable` function see the @storyblok/storyblok-editable README: [@storyblok/storyblok-editable](https://github.com/storyblok/storyblok-editable)
-
-```js
-import React from 'react'
-import { graphql } from 'gatsby'
-import { sbEditable } from "@storyblok/storyblok-editable"
-import DynamicComponent from "../components/dynamicComponent"
-
-export default function StoryblokEntry({ data }) {
- let story = data.storyblokEntry
-
- const components = story.content.body.map(blok => {
- return ()
- })
+export default function StoryblokEntry ({ data }) {
+ const story = data.storyblokEntry
+ story = useStoryblokState(story)
return (
-