@storyblok/react 3.0.13 → 3.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +113 -111
- package/dist/index.js +1 -1
- package/dist/index.mjs +5 -6
- package/dist/rsc.js +1 -1
- package/dist/rsc.mjs +13 -13
- package/dist/storyblok-js.js +2 -2
- package/dist/storyblok-js.mjs +146 -146
- package/dist/types/bridge-loader.d.ts +2 -2
- package/dist/types/common/client.d.ts +1 -1
- package/dist/types/common/index.d.ts +4 -4
- package/dist/types/common/storyblok-component.d.ts +2 -2
- package/dist/types/index.d.ts +3 -3
- package/dist/types/rsc/index.d.ts +4 -4
- package/dist/types/story.d.ts +2 -2
- package/dist/types/types.d.ts +3 -4
- package/package.json +25 -25
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<div align="center">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
<a href="https://www.storyblok.com?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-react" align="center">
|
|
3
|
+
<img src="https://a.storyblok.com/f/88751/1776x360/ccc1c50c67/sb-react.png" alt="Storyblok Logo">
|
|
4
|
+
</a>
|
|
5
|
+
<h1 align="center">@storyblok/react</h1>
|
|
6
6
|
<p align="center">
|
|
7
7
|
The React plugin you need to interact with <a href="http://www.storyblok.com?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-react" target="_blank">Storyblok API</a> and enable the <a href="https://www.storyblok.com/docs/guide/essentials/visual-editor?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-react" target="_blank">Real-time Visual Editing Experience</a>. This package helps you integrate Storyblok with React along with all types of React based frameworks like Next.js, Remix etc. This SDK also includes the support for React Server Side Components.
|
|
8
8
|
</p>
|
|
@@ -63,15 +63,15 @@ Install the file from the CDN:
|
|
|
63
63
|
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=storyblok-react) of your Storyblok space. You can also add the `apiPlugin` in case that you want to use the Storyblok API Client:
|
|
64
64
|
|
|
65
65
|
```js
|
|
66
|
-
import {
|
|
66
|
+
import { apiPlugin, storyblokInit } from '@storyblok/react'
|
|
67
67
|
|
|
68
68
|
/** Import your components */
|
|
69
|
-
import Page from
|
|
70
|
-
import Teaser from
|
|
69
|
+
import Page from './components/Page'
|
|
70
|
+
import Teaser from './components/Teaser'
|
|
71
71
|
// import FallbackComponent from "./components/FallbackComponent";
|
|
72
72
|
|
|
73
73
|
storyblokInit({
|
|
74
|
-
accessToken:
|
|
74
|
+
accessToken: 'YOUR_ACCESS_TOKEN',
|
|
75
75
|
use: [apiPlugin],
|
|
76
76
|
components: {
|
|
77
77
|
page: Page,
|
|
@@ -82,7 +82,7 @@ storyblokInit({
|
|
|
82
82
|
// richText: {},
|
|
83
83
|
// enableFallbackComponent: false,
|
|
84
84
|
// customFallbackComponent: FallbackComponent,
|
|
85
|
-
})
|
|
85
|
+
})
|
|
86
86
|
```
|
|
87
87
|
|
|
88
88
|
> Note: This is the general way for initalizing the SDK, the initialization might be a little different depending upon the framework. You can see how everything works according to the framework in their respective sections below.
|
|
@@ -106,16 +106,16 @@ Possible values:
|
|
|
106
106
|
Full example for a space created in the US:
|
|
107
107
|
|
|
108
108
|
```js
|
|
109
|
-
import {
|
|
109
|
+
import { apiPlugin, storyblokInit } from '@storyblok/react'
|
|
110
110
|
|
|
111
111
|
storyblokInit({
|
|
112
|
-
accessToken:
|
|
112
|
+
accessToken: 'YOUR_ACCESS_TOKEN',
|
|
113
113
|
use: [apiPlugin],
|
|
114
114
|
apiOptions: {
|
|
115
|
-
region:
|
|
115
|
+
region: 'us',
|
|
116
116
|
},
|
|
117
117
|
components: {},
|
|
118
|
-
})
|
|
118
|
+
})
|
|
119
119
|
```
|
|
120
120
|
|
|
121
121
|
> Note: For spaces created in the United States or China, the `region` parameter **must** be specified.
|
|
@@ -129,7 +129,7 @@ storyblokInit({
|
|
|
129
129
|
For every component you've defined in your Storyblok space, call the `storyblokEditable` function with the blok content:
|
|
130
130
|
|
|
131
131
|
```js
|
|
132
|
-
import { storyblokEditable } from
|
|
132
|
+
import { storyblokEditable } from '@storyblok/react'
|
|
133
133
|
|
|
134
134
|
const Feature = ({ blok }) => {
|
|
135
135
|
return (
|
|
@@ -139,10 +139,10 @@ const Feature = ({ blok }) => {
|
|
|
139
139
|
<p>{blok.description}</p>
|
|
140
140
|
</div>
|
|
141
141
|
</div>
|
|
142
|
-
)
|
|
143
|
-
}
|
|
142
|
+
)
|
|
143
|
+
}
|
|
144
144
|
|
|
145
|
-
export default Feature
|
|
145
|
+
export default Feature
|
|
146
146
|
```
|
|
147
147
|
|
|
148
148
|
Where `blok` is the actual blok data coming from [Storyblok's Content Delivery API](https://www.storyblok.com/docs/api/content-delivery?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-react).
|
|
@@ -164,19 +164,19 @@ The initalization remains the same when you work with React. You can intialze th
|
|
|
164
164
|
Use `useStoryblok` to fetch the content as well as enable live editing. You need to pass the `slug` as the first parameter, `apiOptions` as the second parameter, and `bridgeOptions` as the third parameter, which is optional if you want to set the options for the bridge by yourself. Check the available [apiOptions](https://github.com/storyblok/storyblok-js-client#class-storyblok) (passed to `storyblok-js-client`) and [bridgeOptions](https://www.storyblok.com/docs/Guides/storyblok-latest-js?utm_source=github.com&utm_medium=readme&utm_campaign=storyblok-nuxt) (passed to the Storyblok Bridge).
|
|
165
165
|
|
|
166
166
|
```js
|
|
167
|
-
import {
|
|
167
|
+
import { StoryblokComponent, useStoryblok } from '@storyblok/react'
|
|
168
168
|
|
|
169
169
|
function App() {
|
|
170
|
-
const story = useStoryblok(
|
|
170
|
+
const story = useStoryblok('react', { version: 'draft' })
|
|
171
171
|
|
|
172
172
|
if (!story?.content) {
|
|
173
|
-
return <div>Loading...</div
|
|
173
|
+
return <div>Loading...</div>
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
-
return <StoryblokComponent blok={story.content}
|
|
176
|
+
return <StoryblokComponent blok={story.content} />
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
-
export default App
|
|
179
|
+
export default App
|
|
180
180
|
```
|
|
181
181
|
|
|
182
182
|
`StoryblokComponent` renders the route components dynamically, using the list of components loaded during the initialization inside the `storyblokInit` function.
|
|
@@ -186,13 +186,13 @@ This is how you can pass the Bridge options as a third parameter to `useStoryblo
|
|
|
186
186
|
```js
|
|
187
187
|
useStoryblok(
|
|
188
188
|
story.id,
|
|
189
|
-
{ version:
|
|
189
|
+
{ version: 'draft', resolveRelations: ['Article.author'] },
|
|
190
190
|
{
|
|
191
|
-
resolveRelations: [
|
|
192
|
-
resolveLinks:
|
|
191
|
+
resolveRelations: ['Article.author'],
|
|
192
|
+
resolveLinks: 'url',
|
|
193
193
|
preventClicks: true,
|
|
194
194
|
}
|
|
195
|
-
)
|
|
195
|
+
)
|
|
196
196
|
```
|
|
197
197
|
|
|
198
198
|
**Check out our React Boilerplate [here](https://github.com/storyblok/storyblok-react-boilerplate), or read on how to add Storyblok to React in 5 mins [here](https://www.storyblok.com/tp/headless-cms-react)**
|
|
@@ -210,15 +210,15 @@ For more details, refer to the Next.js documentation on [opting out of caching](
|
|
|
210
210
|
|
|
211
211
|
Here's how you can fetch data from Storyblok with `cache: "no-store"`:
|
|
212
212
|
|
|
213
|
-
```
|
|
213
|
+
```typescript
|
|
214
214
|
export async function fetchData() {
|
|
215
|
-
|
|
215
|
+
const sbParams: ISbStoriesParams = { version: 'draft' }
|
|
216
216
|
|
|
217
|
-
const storyblokApi: StoryblokClient = getStoryblokApi()
|
|
217
|
+
const storyblokApi: StoryblokClient = getStoryblokApi()
|
|
218
218
|
|
|
219
219
|
return storyblokApi.get(`cdn/stories/home`, sbParams, {
|
|
220
|
-
cache:
|
|
221
|
-
})
|
|
220
|
+
cache: 'no-store', // This prevents Next.js 13, 14 default caching behaviour
|
|
221
|
+
})
|
|
222
222
|
}
|
|
223
223
|
```
|
|
224
224
|
|
|
@@ -233,13 +233,13 @@ The components in the `app` directory are by default React Server Side Component
|
|
|
233
233
|
In `app/layout.jsx`, call the `storyblokInit` function, but without loading the component list (we will do that on the client). Wrap your whole app using a `StoryblokProvider` component (this provider is created in the next step) :
|
|
234
234
|
|
|
235
235
|
```js
|
|
236
|
-
import {
|
|
237
|
-
import StoryblokProvider from
|
|
236
|
+
import { apiPlugin, storyblokInit } from '@storyblok/react/rsc'
|
|
237
|
+
import StoryblokProvider from '../components/StoryblokProvider'
|
|
238
238
|
|
|
239
239
|
storyblokInit({
|
|
240
|
-
accessToken:
|
|
240
|
+
accessToken: 'YOUR_ACCESS_TOKEN',
|
|
241
241
|
use: [apiPlugin],
|
|
242
|
-
})
|
|
242
|
+
})
|
|
243
243
|
|
|
244
244
|
export default function RootLayout({ children }) {
|
|
245
245
|
return (
|
|
@@ -248,7 +248,7 @@ export default function RootLayout({ children }) {
|
|
|
248
248
|
<body>{children}</body>
|
|
249
249
|
</html>
|
|
250
250
|
</StoryblokProvider>
|
|
251
|
-
)
|
|
251
|
+
)
|
|
252
252
|
}
|
|
253
253
|
```
|
|
254
254
|
|
|
@@ -258,25 +258,25 @@ Create the `components/StoryblokProvider.jsx` file. Re-initalize the connection
|
|
|
258
258
|
|
|
259
259
|
```js
|
|
260
260
|
/** 1. Tag it as a client component */
|
|
261
|
-
|
|
262
|
-
import {
|
|
261
|
+
'use client'
|
|
262
|
+
import { apiPlugin, storyblokInit } from '@storyblok/react/rsc'
|
|
263
263
|
|
|
264
264
|
/** 2. Import your components */
|
|
265
|
-
import Page from
|
|
266
|
-
import Teaser from
|
|
265
|
+
import Page from '../components/Page'
|
|
266
|
+
import Teaser from '../components/Teaser'
|
|
267
267
|
|
|
268
268
|
/** 3. Initialize it as usual */
|
|
269
269
|
storyblokInit({
|
|
270
|
-
accessToken:
|
|
270
|
+
accessToken: 'YOUR_ACCESS_TOKEN',
|
|
271
271
|
use: [apiPlugin],
|
|
272
272
|
components: {
|
|
273
273
|
teaser: Teaser,
|
|
274
274
|
page: Page,
|
|
275
275
|
},
|
|
276
|
-
})
|
|
276
|
+
})
|
|
277
277
|
|
|
278
278
|
export default function StoryblokProvider({ children }) {
|
|
279
|
-
return children
|
|
279
|
+
return children
|
|
280
280
|
}
|
|
281
281
|
```
|
|
282
282
|
|
|
@@ -288,30 +288,30 @@ The `getStoryblokApi` function, which is an instance of [storyblok-js-client](ht
|
|
|
288
288
|
You can render the content of your route with the `StoryblokStory` component, which will automatically handle the Visual Editor live events when editing the story. In `app/page.jsx`, use them as follows:
|
|
289
289
|
|
|
290
290
|
```js
|
|
291
|
-
import { getStoryblokApi, StoryblokStory } from
|
|
291
|
+
import { getStoryblokApi, StoryblokStory } from '@storyblok/react/rsc'
|
|
292
292
|
|
|
293
293
|
export default async function Home() {
|
|
294
|
-
const { data } = await fetchData()
|
|
294
|
+
const { data } = await fetchData()
|
|
295
295
|
|
|
296
296
|
return (
|
|
297
297
|
<div>
|
|
298
298
|
<StoryblokStory story={data.story} />
|
|
299
299
|
</div>
|
|
300
|
-
)
|
|
300
|
+
)
|
|
301
301
|
}
|
|
302
302
|
|
|
303
303
|
export async function fetchData() {
|
|
304
|
-
const storyblokApi = getStoryblokApi()
|
|
305
|
-
return storyblokApi.get(`cdn/stories/home`, { version:
|
|
304
|
+
const storyblokApi = getStoryblokApi()
|
|
305
|
+
return storyblokApi.get(`cdn/stories/home`, { version: 'draft' })
|
|
306
306
|
}
|
|
307
307
|
```
|
|
308
308
|
|
|
309
309
|
`StoryblokStory` keeps the state for thet story behind the scenes and uses `StoryblokComponent` to render the route components dynamically, using the list of components loaded during the initialization inside the `storyblokInit` function. You can use the `StoryblokComponent` inside the components to render the nested components dynamically. You can also pass bridge options to `StoryblokStory` using the prop `bridgeOptions`.
|
|
310
310
|
|
|
311
|
-
```
|
|
312
|
-
const bridgeOptions = { resolveRelations: [
|
|
311
|
+
```jsx
|
|
312
|
+
const bridgeOptions = { resolveRelations: ['article.author'] }
|
|
313
313
|
|
|
314
|
-
<StoryblokStory story={data.story} bridgeOptions={bridgeOptions}
|
|
314
|
+
<StoryblokStory story={data.story} bridgeOptions={bridgeOptions} />
|
|
315
315
|
```
|
|
316
316
|
|
|
317
317
|
> Note: To use this approach (with `getStoryblokApi`), you need to include the `apiPlugin` module when calling `storyblokInit` function. If you don't use `apiPlugin`, you can use your preferred method or function to fetch your data.
|
|
@@ -346,7 +346,7 @@ storyblokInit({
|
|
|
346
346
|
},
|
|
347
347
|
});
|
|
348
348
|
|
|
349
|
-
export default RootLayout({ children }) =>{
|
|
349
|
+
export default RootLayout(({ children }) => {
|
|
350
350
|
const bridgeOptions = { resolveRelations: ["article.author"] };
|
|
351
351
|
|
|
352
352
|
return (
|
|
@@ -366,22 +366,25 @@ The `getStoryblokApi` function, is an instance of [storyblok-js-client](https://
|
|
|
366
366
|
Go to the route you want to fetch data from and use it as follows:
|
|
367
367
|
|
|
368
368
|
```js
|
|
369
|
-
import { getStoryblokApi, StoryblokComponent } from
|
|
369
|
+
import { getStoryblokApi, StoryblokComponent } from '@storyblok/react/rsc'
|
|
370
370
|
|
|
371
371
|
export default async function Home() {
|
|
372
|
-
const { data } = await fetchData()
|
|
372
|
+
const { data } = await fetchData()
|
|
373
373
|
|
|
374
374
|
return (
|
|
375
375
|
<div>
|
|
376
|
-
<h1>
|
|
376
|
+
<h1>
|
|
377
|
+
Story:
|
|
378
|
+
{data.story.id}
|
|
379
|
+
</h1>
|
|
377
380
|
<StoryblokComponent blok={data.story.content} />
|
|
378
381
|
</div>
|
|
379
|
-
)
|
|
382
|
+
)
|
|
380
383
|
}
|
|
381
384
|
|
|
382
385
|
export async function fetchData() {
|
|
383
|
-
const storyblokApi = getStoryblokApi()
|
|
384
|
-
return storyblokApi.get(`cdn/stories/home`, { version:
|
|
386
|
+
const storyblokApi = getStoryblokApi()
|
|
387
|
+
return storyblokApi.get(`cdn/stories/home`, { version: 'draft' })
|
|
385
388
|
}
|
|
386
389
|
```
|
|
387
390
|
|
|
@@ -401,11 +404,11 @@ The initalization remains the same when you work with Next.js. You can intialze
|
|
|
401
404
|
The SDK provides a `getStoryblokApi` object in your app, which is an instance of [storyblok-js-client](https://github.com/storyblok/storyblok-js-client). This can be used to fetch the content from Storyblok. You can use it in functions like `getStaticProps`, `getStaticPaths`, `getServerSideProps` etc.
|
|
402
405
|
|
|
403
406
|
```js
|
|
404
|
-
import { getStoryblokApi } from
|
|
407
|
+
import { getStoryblokApi } from '@storyblok/react'
|
|
405
408
|
|
|
406
409
|
// At the required place
|
|
407
|
-
const storyblokApi = getStoryblokApi()
|
|
408
|
-
const { data } = await storyblokApi.get(
|
|
410
|
+
const storyblokApi = getStoryblokApi()
|
|
411
|
+
const { data } = await storyblokApi.get('cdn/stories', { version: 'draft' })
|
|
409
412
|
```
|
|
410
413
|
|
|
411
414
|
> Note: To use this approach, you need to include the `apiPlugin` module when calling `storyblokInit` function. If you don't use `apiPlugin`, you can use your preferred method or function to fetch your data.
|
|
@@ -415,16 +418,16 @@ const { data } = await storyblokApi.get("cdn/stories", { version: "draft" });
|
|
|
415
418
|
The SDK also provides you with the `useStoryblokState` hook. It works similarly to `useStoryblok` for live editing, but it doesn't fetch the content. Instead, it receives a story object as the first parameter. You can also pass the Bridge Options as the second parameter.
|
|
416
419
|
|
|
417
420
|
```js
|
|
418
|
-
import {
|
|
421
|
+
import { StoryblokComponent, useStoryblokState } from '@storyblok/react'
|
|
419
422
|
|
|
420
423
|
export default function Home({ story: initialStory }) {
|
|
421
|
-
const story = useStoryblokState(initialStory)
|
|
424
|
+
const story = useStoryblokState(initialStory)
|
|
422
425
|
|
|
423
426
|
if (!story.content) {
|
|
424
|
-
return <div>Loading...</div
|
|
427
|
+
return <div>Loading...</div>
|
|
425
428
|
}
|
|
426
429
|
|
|
427
|
-
return <StoryblokComponent blok={story.content}
|
|
430
|
+
return <StoryblokComponent blok={story.content} />
|
|
428
431
|
}
|
|
429
432
|
```
|
|
430
433
|
|
|
@@ -432,26 +435,26 @@ In this case, the story is being passed as a prop that can be coming from where
|
|
|
432
435
|
|
|
433
436
|
```js
|
|
434
437
|
import {
|
|
435
|
-
useStoryblokState,
|
|
436
438
|
getStoryblokApi,
|
|
437
439
|
StoryblokComponent,
|
|
438
|
-
|
|
440
|
+
useStoryblokState,
|
|
441
|
+
} from '@storyblok/react'
|
|
439
442
|
|
|
440
443
|
export default function Home({ story: initialStory }) {
|
|
441
|
-
const story = useStoryblokState(initialStory)
|
|
444
|
+
const story = useStoryblokState(initialStory)
|
|
442
445
|
|
|
443
446
|
if (!story.content) {
|
|
444
|
-
return <div>Loading...</div
|
|
447
|
+
return <div>Loading...</div>
|
|
445
448
|
}
|
|
446
449
|
|
|
447
|
-
return <StoryblokComponent blok={story.content}
|
|
450
|
+
return <StoryblokComponent blok={story.content} />
|
|
448
451
|
}
|
|
449
452
|
|
|
450
453
|
export async function getStaticProps({ preview = false }) {
|
|
451
|
-
const storyblokApi = getStoryblokApi()
|
|
452
|
-
|
|
453
|
-
version:
|
|
454
|
-
})
|
|
454
|
+
const storyblokApi = getStoryblokApi()
|
|
455
|
+
const { data } = await storyblokApi.get(`cdn/stories/react`, {
|
|
456
|
+
version: 'draft',
|
|
457
|
+
})
|
|
455
458
|
|
|
456
459
|
return {
|
|
457
460
|
props: {
|
|
@@ -459,7 +462,7 @@ export async function getStaticProps({ preview = false }) {
|
|
|
459
462
|
preview,
|
|
460
463
|
},
|
|
461
464
|
revalidate: 3600, // revalidate every hour
|
|
462
|
-
}
|
|
465
|
+
}
|
|
463
466
|
}
|
|
464
467
|
```
|
|
465
468
|
|
|
@@ -540,10 +543,10 @@ You can use an `apiOptions` object. This is passed down to the [storyblok-js-cli
|
|
|
540
543
|
|
|
541
544
|
```js
|
|
542
545
|
storyblokInit({
|
|
543
|
-
accessToken:
|
|
546
|
+
accessToken: 'YOUR_ACCESS_TOKEN',
|
|
544
547
|
apiOptions: {
|
|
545
548
|
// storyblok-js-client config object
|
|
546
|
-
cache: { type:
|
|
549
|
+
cache: { type: 'memory' },
|
|
547
550
|
},
|
|
548
551
|
use: [apiPlugin],
|
|
549
552
|
components: {
|
|
@@ -552,13 +555,13 @@ storyblokInit({
|
|
|
552
555
|
grid: Grid,
|
|
553
556
|
feature: Feature,
|
|
554
557
|
},
|
|
555
|
-
})
|
|
558
|
+
})
|
|
556
559
|
```
|
|
557
560
|
|
|
558
561
|
If you prefer to use your own fetch method, just remove the `apiPlugin` and `storyblok-js-client` won't be added to your application.
|
|
559
562
|
|
|
560
563
|
```js
|
|
561
|
-
storyblokInit({})
|
|
564
|
+
storyblokInit({})
|
|
562
565
|
```
|
|
563
566
|
|
|
564
567
|
### Storyblok Bridge
|
|
@@ -566,11 +569,11 @@ storyblokInit({});
|
|
|
566
569
|
If you don't use `registerStoryblokBridge`, you still have access to the raw `window.StoryblokBridge`:
|
|
567
570
|
|
|
568
571
|
```js
|
|
569
|
-
const sbBridge = new window.StoryblokBridge(options)
|
|
572
|
+
const sbBridge = new window.StoryblokBridge(options)
|
|
570
573
|
|
|
571
|
-
sbBridge.on([
|
|
574
|
+
sbBridge.on(['input', 'published', 'change'], (event) => {
|
|
572
575
|
// ...
|
|
573
|
-
})
|
|
576
|
+
})
|
|
574
577
|
```
|
|
575
578
|
|
|
576
579
|
### Rendering Rich Text
|
|
@@ -578,54 +581,53 @@ sbBridge.on(["input", "published", "change"], (event) => {
|
|
|
578
581
|
You can easily render rich text by using the `renderRichText` function that comes with `@storyblok/react`:
|
|
579
582
|
|
|
580
583
|
```js
|
|
581
|
-
import { renderRichText } from
|
|
584
|
+
import { renderRichText } from '@storyblok/react'
|
|
582
585
|
|
|
583
|
-
const renderedRichText = renderRichText(blok.richtext)
|
|
586
|
+
const renderedRichText = renderRichText(blok.richtext)
|
|
584
587
|
```
|
|
585
588
|
|
|
586
589
|
You can set a **custom Schema and component resolver globally** at init time by using the `richText` init option:
|
|
587
590
|
|
|
588
591
|
```js
|
|
589
|
-
import { RichTextSchema, storyblokInit } from
|
|
590
|
-
import cloneDeep from
|
|
592
|
+
import { RichTextSchema, storyblokInit } from '@storyblok/react'
|
|
593
|
+
import cloneDeep from 'clone-deep'
|
|
591
594
|
|
|
592
|
-
const mySchema = cloneDeep(RichTextSchema)
|
|
595
|
+
const mySchema = cloneDeep(RichTextSchema) // you can make a copy of the default RichTextSchema
|
|
593
596
|
// ... and edit the nodes and marks, or add your own.
|
|
594
597
|
// Check the base RichTextSchema source here https://github.com/storyblok/storyblok-js-client/blob/main/src/schema.ts
|
|
595
598
|
|
|
596
599
|
storyblokInit({
|
|
597
|
-
accessToken:
|
|
600
|
+
accessToken: '<your-token>',
|
|
598
601
|
richText: {
|
|
599
602
|
schema: mySchema,
|
|
600
603
|
resolver: (component, blok) => {
|
|
601
604
|
switch (component) {
|
|
602
|
-
case
|
|
603
|
-
return `<div class="my-component-class">${blok.text}</div
|
|
605
|
+
case 'my-custom-component':
|
|
606
|
+
return `<div class="my-component-class">${blok.text}</div>`
|
|
604
607
|
default:
|
|
605
|
-
return
|
|
608
|
+
return 'Resolver not defined'
|
|
606
609
|
}
|
|
607
610
|
},
|
|
608
611
|
},
|
|
609
|
-
})
|
|
612
|
+
})
|
|
610
613
|
```
|
|
611
614
|
|
|
612
615
|
You can also set a **custom Schema and component resolver only once** by passing the options as the second parameter to `renderRichText` function:
|
|
613
616
|
|
|
614
617
|
```js
|
|
615
|
-
import { renderRichText } from
|
|
618
|
+
import { renderRichText } from '@storyblok/react'
|
|
616
619
|
|
|
617
620
|
renderRichText(blok.richTextField, {
|
|
618
621
|
schema: mySchema,
|
|
619
622
|
resolver: (component, blok) => {
|
|
620
623
|
switch (component) {
|
|
621
|
-
case
|
|
622
|
-
return `<div class="my-component-class">${blok.text}</div
|
|
623
|
-
break;
|
|
624
|
+
case 'my-custom-component':
|
|
625
|
+
return `<div class="my-component-class">${blok.text}</div>`
|
|
624
626
|
default:
|
|
625
|
-
return `Component ${component} not found
|
|
627
|
+
return `Component ${component} not found`
|
|
626
628
|
}
|
|
627
629
|
},
|
|
628
|
-
})
|
|
630
|
+
})
|
|
629
631
|
```
|
|
630
632
|
|
|
631
633
|
We also recommend using the [Storyblok Rich Text Renderer for React by Claus](https://github.com/claus/storyblok-rich-text-react-renderer) for rendering your Storyblok rich text content to React elements and Next.js applications.
|
|
@@ -645,36 +647,36 @@ storyblokInit({
|
|
|
645
647
|
components: {
|
|
646
648
|
// all your React components
|
|
647
649
|
},
|
|
648
|
-
})
|
|
650
|
+
})
|
|
649
651
|
```
|
|
650
652
|
|
|
651
653
|
Storyblok's React SDK automatically renders these predefined components based on your page content. While this is convenient, it can lead to larger bundle sizes and slower page speeds, especially for larger sites or when using heavy JavaScript libraries that are only needed on specific pages or a specific component.
|
|
652
654
|
|
|
653
655
|
### Solutions
|
|
654
656
|
|
|
655
|
-
1. **Storyblok's `setComponents` Function**:
|
|
657
|
+
1. **Storyblok's `setComponents` Function**:
|
|
656
658
|
Storyblok SDK provides a function called `setComponents` that allows you to load only the components needed for each route instead of defining all components during initialization. This approach is useful but might not be practical if you use a catch-all route, which is common in many React frameworks.
|
|
657
659
|
|
|
658
|
-
2. **React's `react.lazy`**:
|
|
660
|
+
2. **React's `react.lazy`**:
|
|
659
661
|
React offers a built-in solution called `react.lazy` for code splitting. Instead of directly importing components, you can do the following:
|
|
660
|
-
|
|
662
|
+
|
|
661
663
|
```javascript
|
|
662
|
-
|
|
663
|
-
import {
|
|
664
|
-
import { lazy } from
|
|
665
|
-
|
|
664
|
+
'use client'
|
|
665
|
+
import { apiPlugin, storyblokInit } from '@storyblok/react/rsc'
|
|
666
|
+
import { lazy } from 'react'
|
|
667
|
+
|
|
666
668
|
const lazyComponents = {
|
|
667
|
-
page: lazy(() => import(
|
|
669
|
+
page: lazy(() => import('./components/Page')),
|
|
668
670
|
// other lazy-loaded components
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
+
}
|
|
672
|
+
|
|
671
673
|
storyblokInit({
|
|
672
674
|
accessToken,
|
|
673
675
|
use: [apiPlugin],
|
|
674
676
|
components: lazyComponents,
|
|
675
|
-
})
|
|
677
|
+
})
|
|
676
678
|
```
|
|
677
|
-
|
|
679
|
+
|
|
678
680
|
This approach enables automatic code splitting and loads only the necessary JavaScript for each page. However, `react.lazy` has some limitations when used with SSR (Server-Side Rendering).
|
|
679
681
|
|
|
680
682
|
3. **Using `@loadable/component`**:
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const y=require("react"),e=require("./storyblok-js.js"),o=require("./index2.js"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const y=require("react"),e=require("./storyblok-js.js"),o=require("./index2.js"),k=require("./client.js"),S=require("./storyblok-component.js"),d=(s,r={},t={})=>{const[a,i]=y.useState({}),u=typeof window<"u"&&typeof window.storyblokRegisterEvent<"u",n=o.useStoryblokApi();return y.useEffect(()=>{if(!n){console.error("You can't use useStoryblok if you're not loading apiPlugin.");return}async function b(){const{data:l}=await n.get(`cdn/stories/${s}`,r);i(l.story),u&&l.story.id&&e.registerStoryblokBridge(l.story.id,c=>i(c),t)}b()},[s,JSON.stringify(r),n]),n?(t.resolveRelations=t.resolveRelations??r.resolve_relations,t.resolveLinks=t.resolveLinks??r.resolve_links,a):null};exports.RichTextResolver=e.RichTextResolver;exports.RichTextSchema=e.RichTextSchema;exports.apiPlugin=e.apiPlugin;exports.loadStoryblokBridge=e.loadStoryblokBridge;exports.registerStoryblokBridge=e.registerStoryblokBridge;exports.renderRichText=e.renderRichText;exports.storyblokEditable=e.storyblokEditable;exports.useStoryblokBridge=e.registerStoryblokBridge;exports.getComponent=o.getComponent;exports.getCustomFallbackComponent=o.getCustomFallbackComponent;exports.getEnableFallbackComponent=o.getEnableFallbackComponent;exports.getStoryblokApi=o.useStoryblokApi;exports.setComponents=o.setComponents;exports.storyblokInit=o.storyblokInit;exports.useStoryblokApi=o.useStoryblokApi;exports.useStoryblokState=k.useStoryblokState;exports.StoryblokComponent=S;exports.useStoryblok=d;
|
package/dist/index.mjs
CHANGED
|
@@ -3,11 +3,10 @@ import { registerStoryblokBridge as k } from "./storyblok-js.mjs";
|
|
|
3
3
|
import { RichTextResolver as v, RichTextSchema as x, apiPlugin as R, loadStoryblokBridge as C, renderRichText as w, storyblokEditable as B } from "./storyblok-js.mjs";
|
|
4
4
|
import { useStoryblokApi as c } from "./index2.mjs";
|
|
5
5
|
import { getComponent as h, getCustomFallbackComponent as A, getEnableFallbackComponent as T, setComponents as F, storyblokInit as I } from "./index2.mjs";
|
|
6
|
-
import { useStoryblokState as
|
|
7
|
-
import { default as
|
|
6
|
+
import { useStoryblokState as N } from "./client.mjs";
|
|
7
|
+
import { default as _ } from "./storyblok-component.mjs";
|
|
8
8
|
const b = (s, e = {}, o = {}) => {
|
|
9
|
-
|
|
10
|
-
const i = typeof window < "u" && typeof window.storyblokRegisterEvent < "u", t = c();
|
|
9
|
+
const [l, n] = f({}), i = typeof window < "u" && typeof window.storyblokRegisterEvent < "u", t = c();
|
|
11
10
|
return u(() => {
|
|
12
11
|
if (!t) {
|
|
13
12
|
console.error(
|
|
@@ -32,7 +31,7 @@ const b = (s, e = {}, o = {}) => {
|
|
|
32
31
|
export {
|
|
33
32
|
v as RichTextResolver,
|
|
34
33
|
x as RichTextSchema,
|
|
35
|
-
|
|
34
|
+
_ as StoryblokComponent,
|
|
36
35
|
R as apiPlugin,
|
|
37
36
|
h as getComponent,
|
|
38
37
|
A as getCustomFallbackComponent,
|
|
@@ -47,5 +46,5 @@ export {
|
|
|
47
46
|
b as useStoryblok,
|
|
48
47
|
c as useStoryblokApi,
|
|
49
48
|
k as useStoryblokBridge,
|
|
50
|
-
|
|
49
|
+
N as useStoryblokState
|
|
51
50
|
};
|
package/dist/rsc.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./bridge-loader.js"),o=require("./index2.js"),r=require("./story.js"),l=require("./storyblok-component.js"),e=require("./storyblok-js.js");exports.BridgeLoader=t;exports.StoryblokBridgeLoader=t;exports.getComponent=o.getComponent;exports.getCustomFallbackComponent=o.getCustomFallbackComponent;exports.getEnableFallbackComponent=o.getEnableFallbackComponent;exports.getStoryblokApi=o.useStoryblokApi;exports.setComponents=o.setComponents;exports.storyblokInit=o.storyblokInit;exports.useStoryblokApi=o.useStoryblokApi;exports.StoryblokStory=r;exports.StoryblokComponent=l;exports.RichTextResolver=e.RichTextResolver;exports.RichTextSchema=e.RichTextSchema;exports.apiPlugin=e.apiPlugin;exports.loadStoryblokBridge=e.loadStoryblokBridge;exports.registerStoryblokBridge=e.registerStoryblokBridge;exports.renderRichText=e.renderRichText;exports.storyblokEditable=e.storyblokEditable;exports.useStoryblokBridge=e.registerStoryblokBridge;
|
package/dist/rsc.mjs
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { default as
|
|
1
|
+
import { default as t, default as r } from "./bridge-loader.mjs";
|
|
2
|
+
import { getComponent as a, getCustomFallbackComponent as i, getEnableFallbackComponent as s, useStoryblokApi as b, setComponents as d, storyblokInit as k, useStoryblokApi as n } from "./index2.mjs";
|
|
3
|
+
import { default as g } from "./story.mjs";
|
|
4
4
|
import { default as m } from "./storyblok-component.mjs";
|
|
5
5
|
import { RichTextResolver as f, RichTextSchema as u, apiPlugin as x, loadStoryblokBridge as c, registerStoryblokBridge as B, renderRichText as C, storyblokEditable as h, registerStoryblokBridge as R } from "./storyblok-js.mjs";
|
|
6
6
|
export {
|
|
7
|
-
|
|
7
|
+
t as BridgeLoader,
|
|
8
8
|
f as RichTextResolver,
|
|
9
9
|
u as RichTextSchema,
|
|
10
|
-
|
|
10
|
+
r as StoryblokBridgeLoader,
|
|
11
11
|
m as StoryblokComponent,
|
|
12
|
-
|
|
12
|
+
g as StoryblokStory,
|
|
13
13
|
x as apiPlugin,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
a as getComponent,
|
|
15
|
+
i as getCustomFallbackComponent,
|
|
16
|
+
s as getEnableFallbackComponent,
|
|
17
|
+
b as getStoryblokApi,
|
|
18
18
|
c as loadStoryblokBridge,
|
|
19
19
|
B as registerStoryblokBridge,
|
|
20
20
|
C as renderRichText,
|
|
21
|
-
|
|
21
|
+
d as setComponents,
|
|
22
22
|
h as storyblokEditable,
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
k as storyblokInit,
|
|
24
|
+
n as useStoryblokApi,
|
|
25
25
|
R as useStoryblokBridge
|
|
26
26
|
};
|