@storyblok/js 6.3.0 → 6.3.2
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 +16 -8
- package/dist/index.cjs +180 -0
- package/dist/index.d.cts +82 -0
- package/dist/index.d.mts +82 -0
- package/dist/index.mjs +127 -0
- package/package.json +45 -39
- package/dist/api.d.ts +0 -3
- package/dist/bridge.d.ts +0 -1
- package/dist/editable.d.ts +0 -10
- package/dist/index-CtMAhUF-.js +0 -576
- package/dist/index.d.ts +0 -17
- package/dist/storyblok-js.js +0 -216
- package/dist/storyblok-js.mjs +0 -108
- package/dist/types/index.d.ts +0 -58
package/README.md
CHANGED
|
@@ -35,7 +35,8 @@
|
|
|
35
35
|
|
|
36
36
|
## Documentation
|
|
37
37
|
|
|
38
|
-
For complete documentation, please visit
|
|
38
|
+
For complete documentation, please visit
|
|
39
|
+
[package reference](https://www.storyblok.com/docs/packages/storyblok-js)
|
|
39
40
|
|
|
40
41
|
## Contributing
|
|
41
42
|
|
|
@@ -43,7 +44,8 @@ If you'd like to contribute, please refer to the [contributing guidelines](CONTR
|
|
|
43
44
|
|
|
44
45
|
## Community
|
|
45
46
|
|
|
46
|
-
For help, discussion about best practices, or any other conversation that would benefit from being
|
|
47
|
+
For help, discussion about best practices, or any other conversation that would benefit from being
|
|
48
|
+
searchable:
|
|
47
49
|
|
|
48
50
|
- [Discuss Storyblok on GitHub Discussions](https://github.com/storyblok/monoblok/discussions)
|
|
49
51
|
|
|
@@ -53,19 +55,25 @@ For community support, chatting with other users, please visit:
|
|
|
53
55
|
|
|
54
56
|
## Support
|
|
55
57
|
|
|
56
|
-
For bugs or feature requests, please
|
|
58
|
+
For bugs or feature requests, please
|
|
59
|
+
[submit an issue](https://github.com/storyblok/monoblok/issues/new/choose).
|
|
57
60
|
|
|
58
|
-
> [!IMPORTANT]
|
|
59
|
-
>
|
|
61
|
+
> [!IMPORTANT] Please search existing issues before submitting a new one. Issues without a minimal
|
|
62
|
+
> reproducible example will be closed.
|
|
63
|
+
> [Why reproductions are Required](https://antfu.me/posts/why-reproductions-are-required).
|
|
60
64
|
|
|
61
65
|
### I can't share my company project code
|
|
62
66
|
|
|
63
|
-
We understand that you might not be able to share your company's project code. Please provide a
|
|
67
|
+
We understand that you might not be able to share your company's project code. Please provide a
|
|
68
|
+
minimal reproducible example that demonstrates the issue by using tools like
|
|
69
|
+
[Stackblitz](https://stackblitz.com) or a link to a GitHub repo. Please make sure you include a
|
|
70
|
+
README file with the instructions to build and run the project, important not to include any access
|
|
71
|
+
token, password or personal information of any kind.
|
|
64
72
|
|
|
65
73
|
### Feedback
|
|
66
74
|
|
|
67
|
-
If you have a question, please ask in the
|
|
68
|
-
|
|
75
|
+
If you have a question, please ask in the
|
|
76
|
+
[Discuss Storyblok on Discord](https://storyblok.com/join-discord) channel.
|
|
69
77
|
|
|
70
78
|
## License
|
|
71
79
|
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* name: @storyblok/js
|
|
3
|
+
* (c) 2026
|
|
4
|
+
* description: SDK to integrate Storyblok into your project using JavaScript.
|
|
5
|
+
* author: undefined
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
8
|
+
//#region \0rolldown/runtime.js
|
|
9
|
+
var __create = Object.create;
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
14
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
15
|
+
var __copyProps = (to, from, except, desc) => {
|
|
16
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
17
|
+
key = keys[i];
|
|
18
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
19
|
+
get: ((k) => from[k]).bind(null, key),
|
|
20
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
return to;
|
|
24
|
+
};
|
|
25
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
26
|
+
value: mod,
|
|
27
|
+
enumerable: true
|
|
28
|
+
}) : target, mod));
|
|
29
|
+
//#endregion
|
|
30
|
+
let storyblok_js_client = require("storyblok-js-client");
|
|
31
|
+
storyblok_js_client = __toESM(storyblok_js_client, 1);
|
|
32
|
+
let _storyblok_richtext = require("@storyblok/richtext");
|
|
33
|
+
//#region src/bridge.ts
|
|
34
|
+
let loaded = false;
|
|
35
|
+
let loadPromise;
|
|
36
|
+
const callbacks = [];
|
|
37
|
+
const loadBridge = () => {
|
|
38
|
+
if (typeof window === "undefined") return Promise.reject(/* @__PURE__ */ new Error("Cannot load Storyblok bridge: window is undefined (server-side environment)"));
|
|
39
|
+
window.storyblokRegisterEvent = (cb) => {
|
|
40
|
+
if (!window.location.search.includes("_storyblok")) {
|
|
41
|
+
console.warn("You are not in Draft Mode or in the Visual Editor.");
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (!loaded) callbacks.push(cb);
|
|
45
|
+
else cb();
|
|
46
|
+
};
|
|
47
|
+
if (loaded) return Promise.resolve();
|
|
48
|
+
if (loadPromise) return loadPromise;
|
|
49
|
+
loadPromise = import("@storyblok/preview-bridge").then(({ default: StoryblokBridgeClass }) => {
|
|
50
|
+
window.StoryblokBridge = StoryblokBridgeClass;
|
|
51
|
+
callbacks.forEach((cb) => cb());
|
|
52
|
+
loaded = true;
|
|
53
|
+
}).catch((error) => {
|
|
54
|
+
loadPromise = void 0;
|
|
55
|
+
throw error;
|
|
56
|
+
});
|
|
57
|
+
return loadPromise;
|
|
58
|
+
};
|
|
59
|
+
//#endregion
|
|
60
|
+
//#region src/api.ts
|
|
61
|
+
const apiFactory = (options = {}) => {
|
|
62
|
+
const { apiOptions } = options;
|
|
63
|
+
if (!apiOptions || !apiOptions.accessToken) {
|
|
64
|
+
console.error("You need to provide an access token to interact with Storyblok API. Read https://www.storyblok.com/docs/api/content-delivery#topics/authentication");
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
return { storyblokApi: new storyblok_js_client.default(apiOptions) };
|
|
68
|
+
};
|
|
69
|
+
//#endregion
|
|
70
|
+
//#region src/editable.ts
|
|
71
|
+
var editable_default = (blok) => {
|
|
72
|
+
if (typeof blok !== "object" || typeof blok._editable !== "string") return {};
|
|
73
|
+
try {
|
|
74
|
+
const options = JSON.parse(blok._editable.replace(/^<!--#storyblok#/, "").replace(/-->$/, ""));
|
|
75
|
+
if (options) return {
|
|
76
|
+
"data-blok-c": JSON.stringify(options),
|
|
77
|
+
"data-blok-uid": `${options.id}-${options.uid}`
|
|
78
|
+
};
|
|
79
|
+
return {};
|
|
80
|
+
} catch {
|
|
81
|
+
return {};
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
//#endregion
|
|
85
|
+
//#region src/index.ts
|
|
86
|
+
/**
|
|
87
|
+
* Normalises StoryblokBridgeConfigV2 options for the bundled
|
|
88
|
+
* @storyblok/preview-bridge constructor, which has a slightly different
|
|
89
|
+
* BridgeParams shape than the legacy CDN bridge.
|
|
90
|
+
*
|
|
91
|
+
* Changes applied:
|
|
92
|
+
* - `resolveRelations` string → string[] (CDN bridge accepted both; bundled
|
|
93
|
+
* bridge only accepts string[])
|
|
94
|
+
* - `language` → removed with a deprecation warning (the new bridge receives
|
|
95
|
+
* language context via the `_storyblok_lang` URL parameter set by the
|
|
96
|
+
* Visual Editor; it no longer needs to be passed as a constructor option)
|
|
97
|
+
* - `resolveLinks: 'link'` → passed through unchanged. The official docs list
|
|
98
|
+
* it as a valid value; the TypeScript BridgeParams type omitting it is a
|
|
99
|
+
* types/docs gap, not a runtime restriction.
|
|
100
|
+
*/
|
|
101
|
+
function normalizeBridgeOptions(options) {
|
|
102
|
+
const { language, resolveRelations, ...rest } = options;
|
|
103
|
+
if (language) console.warn("[Storyblok] The `language` bridge option is no longer supported by the bundled bridge. Language context is now passed automatically by the Visual Editor via the `_storyblok_lang` URL parameter.");
|
|
104
|
+
return {
|
|
105
|
+
...rest,
|
|
106
|
+
...resolveRelations !== void 0 && { resolveRelations: Array.isArray(resolveRelations) ? resolveRelations : [resolveRelations] }
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
const useStoryblokBridge = (id, cb, options = {}) => {
|
|
110
|
+
const isBridgeLoaded = !(typeof window === "undefined") && typeof window.storyblokRegisterEvent !== "undefined";
|
|
111
|
+
const storyId = new URL(window.location?.href).searchParams.get("_storyblok");
|
|
112
|
+
const inStory = storyId !== null && +storyId === id;
|
|
113
|
+
if (!isBridgeLoaded || !inStory) return;
|
|
114
|
+
if (!id) {
|
|
115
|
+
console.warn("Story ID is not defined. Please provide a valid ID.");
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
window.storyblokRegisterEvent(() => {
|
|
119
|
+
new window.StoryblokBridge(normalizeBridgeOptions(options)).on([
|
|
120
|
+
"input",
|
|
121
|
+
"published",
|
|
122
|
+
"change"
|
|
123
|
+
], (event) => {
|
|
124
|
+
if (!event) return;
|
|
125
|
+
if (event.action === "input" && event.story?.id === id) cb(event.story);
|
|
126
|
+
else if ((event.action === "change" || event.action === "published") && event.storyId === id) window.location.reload();
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
};
|
|
130
|
+
const storyblokInit = (pluginOptions = {}) => {
|
|
131
|
+
const { bridge, accessToken, use = [], apiOptions = {}, bridgeUrl } = pluginOptions;
|
|
132
|
+
if (bridgeUrl) console.warn("[Storyblok] The `bridgeUrl` option is deprecated and will be removed in a future major version. The Storyblok bridge is now bundled and is no longer loaded from a CDN URL.");
|
|
133
|
+
apiOptions.accessToken = apiOptions.accessToken || accessToken;
|
|
134
|
+
const options = {
|
|
135
|
+
bridge,
|
|
136
|
+
apiOptions
|
|
137
|
+
};
|
|
138
|
+
let result = {};
|
|
139
|
+
use.forEach((pluginFactory) => {
|
|
140
|
+
result = {
|
|
141
|
+
...result,
|
|
142
|
+
...pluginFactory(options)
|
|
143
|
+
};
|
|
144
|
+
});
|
|
145
|
+
const inEditor = !(typeof window === "undefined") && window.location?.search?.includes("_storyblok_tk");
|
|
146
|
+
if (bridge !== false && inEditor) loadBridge();
|
|
147
|
+
return result;
|
|
148
|
+
};
|
|
149
|
+
const loadStoryblokBridge = () => loadBridge();
|
|
150
|
+
//#endregion
|
|
151
|
+
Object.defineProperty(exports, "StoryblokClient", {
|
|
152
|
+
enumerable: true,
|
|
153
|
+
get: function() {
|
|
154
|
+
return storyblok_js_client.default;
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
exports.apiPlugin = apiFactory;
|
|
158
|
+
Object.defineProperty(exports, "buildStoryblokImage", {
|
|
159
|
+
enumerable: true,
|
|
160
|
+
get: function() {
|
|
161
|
+
return _storyblok_richtext.buildStoryblokImage;
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
exports.loadStoryblokBridge = loadStoryblokBridge;
|
|
165
|
+
exports.registerStoryblokBridge = useStoryblokBridge;
|
|
166
|
+
exports.useStoryblokBridge = useStoryblokBridge;
|
|
167
|
+
Object.defineProperty(exports, "renderRichText", {
|
|
168
|
+
enumerable: true,
|
|
169
|
+
get: function() {
|
|
170
|
+
return _storyblok_richtext.renderRichText;
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
Object.defineProperty(exports, "splitTableRows", {
|
|
174
|
+
enumerable: true,
|
|
175
|
+
get: function() {
|
|
176
|
+
return _storyblok_richtext.splitTableRows;
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
exports.storyblokEditable = editable_default;
|
|
180
|
+
exports.storyblokInit = storyblokInit;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* name: @storyblok/js
|
|
3
|
+
* (c) 2026
|
|
4
|
+
* description: SDK to integrate Storyblok into your project using JavaScript.
|
|
5
|
+
* author: undefined
|
|
6
|
+
*/
|
|
7
|
+
import StoryblokClient, { ArrayFn, AsyncFn, ISbAlternateObject, ISbCache, ISbComponentType, ISbComponentType as StoryblokComponentType, ISbConfig, ISbConfig as ISbConfig$1, ISbContentMangmntAPI, ISbDimensions, ISbError, ISbManagmentApiResult, ISbResponse, ISbResult, ISbSchema, ISbStories, ISbStoriesParams, ISbStory, ISbStoryData, ISbStoryData as ISbStoryData$1, ISbStoryParams, ISbThrottle, ISbThrottledRequest, default as StoryblokClient$1 } from "storyblok-js-client";
|
|
8
|
+
import { BridgeParams } from "@storyblok/preview-bridge";
|
|
9
|
+
import { SbRichTextDoc, SbRichTextImageOptions, SbRichTextMark, SbRichTextNode, SbRichTextProps, SbRichTextRenderContext, SbRichTextRendererMap, buildStoryblokImage, renderRichText, splitTableRows } from "@storyblok/richtext";
|
|
10
|
+
//#region src/types/index.d.ts
|
|
11
|
+
declare global {
|
|
12
|
+
interface Window {
|
|
13
|
+
storyblokRegisterEvent: (cb: () => void) => void;
|
|
14
|
+
StoryblokBridge: {
|
|
15
|
+
new (options?: StoryblokBridgeConfigV2): StoryblokBridgeV2;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
interface SbInitResult {
|
|
20
|
+
storyblokApi?: StoryblokClient$1;
|
|
21
|
+
}
|
|
22
|
+
type SbPluginFactory = (options: SbSDKOptions) => any;
|
|
23
|
+
type SbBlokKeyDataTypes = string | number | object | boolean | undefined;
|
|
24
|
+
interface SbBlokData extends ISbComponentType<string> {
|
|
25
|
+
[index: string]: SbBlokKeyDataTypes;
|
|
26
|
+
}
|
|
27
|
+
interface SbSDKOptions {
|
|
28
|
+
bridge?: boolean;
|
|
29
|
+
accessToken?: string;
|
|
30
|
+
use?: any[];
|
|
31
|
+
apiOptions?: ISbConfig$1;
|
|
32
|
+
bridgeUrl?: string;
|
|
33
|
+
}
|
|
34
|
+
interface ISbEventPayload<S extends ISbComponentType<string> = any> {
|
|
35
|
+
action: "customEvent" | "published" | "input" | "change" | "unpublished" | "enterEditmode";
|
|
36
|
+
event?: string;
|
|
37
|
+
story?: ISbStoryData$1<S>;
|
|
38
|
+
slug?: string;
|
|
39
|
+
slugChanged?: boolean;
|
|
40
|
+
storyId?: number;
|
|
41
|
+
reload?: boolean;
|
|
42
|
+
}
|
|
43
|
+
interface StoryblokBridgeConfigV2 {
|
|
44
|
+
resolveRelations?: string | string[];
|
|
45
|
+
customParent?: string;
|
|
46
|
+
preventClicks?: boolean;
|
|
47
|
+
language?: string;
|
|
48
|
+
resolveLinks?: "url" | "story" | "0" | "1" | "link";
|
|
49
|
+
fallbackLang?: string;
|
|
50
|
+
}
|
|
51
|
+
interface StoryblokBridgeV2 {
|
|
52
|
+
pingEditor: (event: any) => void;
|
|
53
|
+
isInEditor: () => boolean;
|
|
54
|
+
enterEditmode: () => void;
|
|
55
|
+
on: (event: "customEvent" | "published" | "input" | "change" | "unpublished" | "enterEditmode" | string[], callback: (payload?: ISbEventPayload) => void) => void;
|
|
56
|
+
}
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/api.d.ts
|
|
59
|
+
declare const apiFactory: SbPluginFactory;
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region src/editable.d.ts
|
|
62
|
+
declare const _default: (blok?: {
|
|
63
|
+
_editable?: string;
|
|
64
|
+
}) => {
|
|
65
|
+
"data-blok-c"?: undefined;
|
|
66
|
+
"data-blok-uid"?: undefined;
|
|
67
|
+
} | {
|
|
68
|
+
"data-blok-c": string;
|
|
69
|
+
"data-blok-uid": string;
|
|
70
|
+
};
|
|
71
|
+
//#endregion
|
|
72
|
+
//#region src/index.d.ts
|
|
73
|
+
interface StoryblokBridgeEvent {
|
|
74
|
+
action: string;
|
|
75
|
+
storyId: number;
|
|
76
|
+
story: ISbStoryData;
|
|
77
|
+
}
|
|
78
|
+
declare const useStoryblokBridge: <T extends StoryblokComponentType<string> = any>(id: number, cb: (newStory: ISbStoryData<T>) => void, options?: StoryblokBridgeConfigV2) => void;
|
|
79
|
+
declare const storyblokInit: (pluginOptions?: SbSDKOptions) => SbInitResult;
|
|
80
|
+
declare const loadStoryblokBridge: () => Promise<void>;
|
|
81
|
+
//#endregion
|
|
82
|
+
export { type ArrayFn, type AsyncFn, type BridgeParams, type ISbAlternateObject, type ISbCache, type ISbConfig, type ISbContentMangmntAPI, type ISbDimensions, type ISbError, ISbEventPayload, type ISbManagmentApiResult, type ISbResponse, type ISbResult, type ISbSchema, type ISbStories, type ISbStoriesParams, type ISbStory, type ISbStoryData, type ISbStoryParams, type ISbThrottle, type ISbThrottledRequest, SbBlokData, SbBlokKeyDataTypes, SbInitResult, SbPluginFactory, type SbRichTextDoc, type SbRichTextImageOptions, type SbRichTextMark, type SbRichTextNode, type SbRichTextProps, type SbRichTextRenderContext, type SbRichTextRendererMap, SbSDKOptions, StoryblokBridgeConfigV2, StoryblokBridgeEvent, StoryblokBridgeV2, StoryblokClient, type StoryblokComponentType, apiFactory as apiPlugin, buildStoryblokImage, loadStoryblokBridge, useStoryblokBridge as registerStoryblokBridge, useStoryblokBridge, renderRichText, splitTableRows, _default as storyblokEditable, storyblokInit };
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* name: @storyblok/js
|
|
3
|
+
* (c) 2026
|
|
4
|
+
* description: SDK to integrate Storyblok into your project using JavaScript.
|
|
5
|
+
* author: undefined
|
|
6
|
+
*/
|
|
7
|
+
import StoryblokClient, { ArrayFn, AsyncFn, ISbAlternateObject, ISbCache, ISbComponentType, ISbComponentType as StoryblokComponentType, ISbConfig, ISbConfig as ISbConfig$1, ISbContentMangmntAPI, ISbDimensions, ISbError, ISbManagmentApiResult, ISbResponse, ISbResult, ISbSchema, ISbStories, ISbStoriesParams, ISbStory, ISbStoryData, ISbStoryData as ISbStoryData$1, ISbStoryParams, ISbThrottle, ISbThrottledRequest, default as StoryblokClient$1 } from "storyblok-js-client";
|
|
8
|
+
import { SbRichTextDoc, SbRichTextImageOptions, SbRichTextMark, SbRichTextNode, SbRichTextProps, SbRichTextRenderContext, SbRichTextRendererMap, buildStoryblokImage, renderRichText, splitTableRows } from "@storyblok/richtext";
|
|
9
|
+
import { BridgeParams } from "@storyblok/preview-bridge";
|
|
10
|
+
//#region src/types/index.d.ts
|
|
11
|
+
declare global {
|
|
12
|
+
interface Window {
|
|
13
|
+
storyblokRegisterEvent: (cb: () => void) => void;
|
|
14
|
+
StoryblokBridge: {
|
|
15
|
+
new (options?: StoryblokBridgeConfigV2): StoryblokBridgeV2;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
interface SbInitResult {
|
|
20
|
+
storyblokApi?: StoryblokClient$1;
|
|
21
|
+
}
|
|
22
|
+
type SbPluginFactory = (options: SbSDKOptions) => any;
|
|
23
|
+
type SbBlokKeyDataTypes = string | number | object | boolean | undefined;
|
|
24
|
+
interface SbBlokData extends ISbComponentType<string> {
|
|
25
|
+
[index: string]: SbBlokKeyDataTypes;
|
|
26
|
+
}
|
|
27
|
+
interface SbSDKOptions {
|
|
28
|
+
bridge?: boolean;
|
|
29
|
+
accessToken?: string;
|
|
30
|
+
use?: any[];
|
|
31
|
+
apiOptions?: ISbConfig$1;
|
|
32
|
+
bridgeUrl?: string;
|
|
33
|
+
}
|
|
34
|
+
interface ISbEventPayload<S extends ISbComponentType<string> = any> {
|
|
35
|
+
action: "customEvent" | "published" | "input" | "change" | "unpublished" | "enterEditmode";
|
|
36
|
+
event?: string;
|
|
37
|
+
story?: ISbStoryData$1<S>;
|
|
38
|
+
slug?: string;
|
|
39
|
+
slugChanged?: boolean;
|
|
40
|
+
storyId?: number;
|
|
41
|
+
reload?: boolean;
|
|
42
|
+
}
|
|
43
|
+
interface StoryblokBridgeConfigV2 {
|
|
44
|
+
resolveRelations?: string | string[];
|
|
45
|
+
customParent?: string;
|
|
46
|
+
preventClicks?: boolean;
|
|
47
|
+
language?: string;
|
|
48
|
+
resolveLinks?: "url" | "story" | "0" | "1" | "link";
|
|
49
|
+
fallbackLang?: string;
|
|
50
|
+
}
|
|
51
|
+
interface StoryblokBridgeV2 {
|
|
52
|
+
pingEditor: (event: any) => void;
|
|
53
|
+
isInEditor: () => boolean;
|
|
54
|
+
enterEditmode: () => void;
|
|
55
|
+
on: (event: "customEvent" | "published" | "input" | "change" | "unpublished" | "enterEditmode" | string[], callback: (payload?: ISbEventPayload) => void) => void;
|
|
56
|
+
}
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/api.d.ts
|
|
59
|
+
declare const apiFactory: SbPluginFactory;
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region src/editable.d.ts
|
|
62
|
+
declare const _default: (blok?: {
|
|
63
|
+
_editable?: string;
|
|
64
|
+
}) => {
|
|
65
|
+
"data-blok-c"?: undefined;
|
|
66
|
+
"data-blok-uid"?: undefined;
|
|
67
|
+
} | {
|
|
68
|
+
"data-blok-c": string;
|
|
69
|
+
"data-blok-uid": string;
|
|
70
|
+
};
|
|
71
|
+
//#endregion
|
|
72
|
+
//#region src/index.d.ts
|
|
73
|
+
interface StoryblokBridgeEvent {
|
|
74
|
+
action: string;
|
|
75
|
+
storyId: number;
|
|
76
|
+
story: ISbStoryData;
|
|
77
|
+
}
|
|
78
|
+
declare const useStoryblokBridge: <T extends StoryblokComponentType<string> = any>(id: number, cb: (newStory: ISbStoryData<T>) => void, options?: StoryblokBridgeConfigV2) => void;
|
|
79
|
+
declare const storyblokInit: (pluginOptions?: SbSDKOptions) => SbInitResult;
|
|
80
|
+
declare const loadStoryblokBridge: () => Promise<void>;
|
|
81
|
+
//#endregion
|
|
82
|
+
export { type ArrayFn, type AsyncFn, type BridgeParams, type ISbAlternateObject, type ISbCache, type ISbConfig, type ISbContentMangmntAPI, type ISbDimensions, type ISbError, ISbEventPayload, type ISbManagmentApiResult, type ISbResponse, type ISbResult, type ISbSchema, type ISbStories, type ISbStoriesParams, type ISbStory, type ISbStoryData, type ISbStoryParams, type ISbThrottle, type ISbThrottledRequest, SbBlokData, SbBlokKeyDataTypes, SbInitResult, SbPluginFactory, type SbRichTextDoc, type SbRichTextImageOptions, type SbRichTextMark, type SbRichTextNode, type SbRichTextProps, type SbRichTextRenderContext, type SbRichTextRendererMap, SbSDKOptions, StoryblokBridgeConfigV2, StoryblokBridgeEvent, StoryblokBridgeV2, StoryblokClient, type StoryblokComponentType, apiFactory as apiPlugin, buildStoryblokImage, loadStoryblokBridge, useStoryblokBridge as registerStoryblokBridge, useStoryblokBridge, renderRichText, splitTableRows, _default as storyblokEditable, storyblokInit };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* name: @storyblok/js
|
|
3
|
+
* (c) 2026
|
|
4
|
+
* description: SDK to integrate Storyblok into your project using JavaScript.
|
|
5
|
+
* author: undefined
|
|
6
|
+
*/
|
|
7
|
+
import StoryblokClient, { default as StoryblokClient$1 } from "storyblok-js-client";
|
|
8
|
+
import { buildStoryblokImage, renderRichText, splitTableRows } from "@storyblok/richtext";
|
|
9
|
+
//#region src/bridge.ts
|
|
10
|
+
let loaded = false;
|
|
11
|
+
let loadPromise;
|
|
12
|
+
const callbacks = [];
|
|
13
|
+
const loadBridge = () => {
|
|
14
|
+
if (typeof window === "undefined") return Promise.reject(/* @__PURE__ */ new Error("Cannot load Storyblok bridge: window is undefined (server-side environment)"));
|
|
15
|
+
window.storyblokRegisterEvent = (cb) => {
|
|
16
|
+
if (!window.location.search.includes("_storyblok")) {
|
|
17
|
+
console.warn("You are not in Draft Mode or in the Visual Editor.");
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (!loaded) callbacks.push(cb);
|
|
21
|
+
else cb();
|
|
22
|
+
};
|
|
23
|
+
if (loaded) return Promise.resolve();
|
|
24
|
+
if (loadPromise) return loadPromise;
|
|
25
|
+
loadPromise = import("@storyblok/preview-bridge").then(({ default: StoryblokBridgeClass }) => {
|
|
26
|
+
window.StoryblokBridge = StoryblokBridgeClass;
|
|
27
|
+
callbacks.forEach((cb) => cb());
|
|
28
|
+
loaded = true;
|
|
29
|
+
}).catch((error) => {
|
|
30
|
+
loadPromise = void 0;
|
|
31
|
+
throw error;
|
|
32
|
+
});
|
|
33
|
+
return loadPromise;
|
|
34
|
+
};
|
|
35
|
+
//#endregion
|
|
36
|
+
//#region src/api.ts
|
|
37
|
+
const apiFactory = (options = {}) => {
|
|
38
|
+
const { apiOptions } = options;
|
|
39
|
+
if (!apiOptions || !apiOptions.accessToken) {
|
|
40
|
+
console.error("You need to provide an access token to interact with Storyblok API. Read https://www.storyblok.com/docs/api/content-delivery#topics/authentication");
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
return { storyblokApi: new StoryblokClient$1(apiOptions) };
|
|
44
|
+
};
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region src/editable.ts
|
|
47
|
+
var editable_default = (blok) => {
|
|
48
|
+
if (typeof blok !== "object" || typeof blok._editable !== "string") return {};
|
|
49
|
+
try {
|
|
50
|
+
const options = JSON.parse(blok._editable.replace(/^<!--#storyblok#/, "").replace(/-->$/, ""));
|
|
51
|
+
if (options) return {
|
|
52
|
+
"data-blok-c": JSON.stringify(options),
|
|
53
|
+
"data-blok-uid": `${options.id}-${options.uid}`
|
|
54
|
+
};
|
|
55
|
+
return {};
|
|
56
|
+
} catch {
|
|
57
|
+
return {};
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region src/index.ts
|
|
62
|
+
/**
|
|
63
|
+
* Normalises StoryblokBridgeConfigV2 options for the bundled
|
|
64
|
+
* @storyblok/preview-bridge constructor, which has a slightly different
|
|
65
|
+
* BridgeParams shape than the legacy CDN bridge.
|
|
66
|
+
*
|
|
67
|
+
* Changes applied:
|
|
68
|
+
* - `resolveRelations` string → string[] (CDN bridge accepted both; bundled
|
|
69
|
+
* bridge only accepts string[])
|
|
70
|
+
* - `language` → removed with a deprecation warning (the new bridge receives
|
|
71
|
+
* language context via the `_storyblok_lang` URL parameter set by the
|
|
72
|
+
* Visual Editor; it no longer needs to be passed as a constructor option)
|
|
73
|
+
* - `resolveLinks: 'link'` → passed through unchanged. The official docs list
|
|
74
|
+
* it as a valid value; the TypeScript BridgeParams type omitting it is a
|
|
75
|
+
* types/docs gap, not a runtime restriction.
|
|
76
|
+
*/
|
|
77
|
+
function normalizeBridgeOptions(options) {
|
|
78
|
+
const { language, resolveRelations, ...rest } = options;
|
|
79
|
+
if (language) console.warn("[Storyblok] The `language` bridge option is no longer supported by the bundled bridge. Language context is now passed automatically by the Visual Editor via the `_storyblok_lang` URL parameter.");
|
|
80
|
+
return {
|
|
81
|
+
...rest,
|
|
82
|
+
...resolveRelations !== void 0 && { resolveRelations: Array.isArray(resolveRelations) ? resolveRelations : [resolveRelations] }
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
const useStoryblokBridge = (id, cb, options = {}) => {
|
|
86
|
+
const isBridgeLoaded = !(typeof window === "undefined") && typeof window.storyblokRegisterEvent !== "undefined";
|
|
87
|
+
const storyId = new URL(window.location?.href).searchParams.get("_storyblok");
|
|
88
|
+
const inStory = storyId !== null && +storyId === id;
|
|
89
|
+
if (!isBridgeLoaded || !inStory) return;
|
|
90
|
+
if (!id) {
|
|
91
|
+
console.warn("Story ID is not defined. Please provide a valid ID.");
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
window.storyblokRegisterEvent(() => {
|
|
95
|
+
new window.StoryblokBridge(normalizeBridgeOptions(options)).on([
|
|
96
|
+
"input",
|
|
97
|
+
"published",
|
|
98
|
+
"change"
|
|
99
|
+
], (event) => {
|
|
100
|
+
if (!event) return;
|
|
101
|
+
if (event.action === "input" && event.story?.id === id) cb(event.story);
|
|
102
|
+
else if ((event.action === "change" || event.action === "published") && event.storyId === id) window.location.reload();
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
const storyblokInit = (pluginOptions = {}) => {
|
|
107
|
+
const { bridge, accessToken, use = [], apiOptions = {}, bridgeUrl } = pluginOptions;
|
|
108
|
+
if (bridgeUrl) console.warn("[Storyblok] The `bridgeUrl` option is deprecated and will be removed in a future major version. The Storyblok bridge is now bundled and is no longer loaded from a CDN URL.");
|
|
109
|
+
apiOptions.accessToken = apiOptions.accessToken || accessToken;
|
|
110
|
+
const options = {
|
|
111
|
+
bridge,
|
|
112
|
+
apiOptions
|
|
113
|
+
};
|
|
114
|
+
let result = {};
|
|
115
|
+
use.forEach((pluginFactory) => {
|
|
116
|
+
result = {
|
|
117
|
+
...result,
|
|
118
|
+
...pluginFactory(options)
|
|
119
|
+
};
|
|
120
|
+
});
|
|
121
|
+
const inEditor = !(typeof window === "undefined") && window.location?.search?.includes("_storyblok_tk");
|
|
122
|
+
if (bridge !== false && inEditor) loadBridge();
|
|
123
|
+
return result;
|
|
124
|
+
};
|
|
125
|
+
const loadStoryblokBridge = () => loadBridge();
|
|
126
|
+
//#endregion
|
|
127
|
+
export { StoryblokClient, apiFactory as apiPlugin, buildStoryblokImage, loadStoryblokBridge, useStoryblokBridge as registerStoryblokBridge, useStoryblokBridge, renderRichText, splitTableRows, editable_default as storyblokEditable, storyblokInit };
|
package/package.json
CHANGED
|
@@ -1,56 +1,59 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@storyblok/js",
|
|
3
|
-
"
|
|
4
|
-
"version": "6.3.0",
|
|
3
|
+
"version": "6.3.2",
|
|
5
4
|
"private": false,
|
|
6
5
|
"description": "SDK to integrate Storyblok into your project using JavaScript.",
|
|
7
|
-
"license": "MIT",
|
|
8
6
|
"homepage": "https://github.com/storyblok/monoblok/tree/main/packages/js#readme",
|
|
7
|
+
"bugs": {
|
|
8
|
+
"url": "https://github.com/storyblok/monoblok/issues"
|
|
9
|
+
},
|
|
10
|
+
"license": "MIT",
|
|
9
11
|
"repository": {
|
|
10
12
|
"type": "git",
|
|
11
|
-
"url": "https://github.com/storyblok/monoblok.git",
|
|
13
|
+
"url": "git+https://github.com/storyblok/monoblok.git",
|
|
12
14
|
"directory": "packages/js"
|
|
13
15
|
},
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"type": "module",
|
|
17
20
|
"sideEffects": false,
|
|
21
|
+
"main": "./dist/index.cjs",
|
|
22
|
+
"module": "./dist/index.mjs",
|
|
23
|
+
"types": "./dist/index.d.cts",
|
|
18
24
|
"exports": {
|
|
19
25
|
".": {
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
26
|
+
"import": {
|
|
27
|
+
"types": "./dist/index.d.mts",
|
|
28
|
+
"default": "./dist/index.mjs"
|
|
29
|
+
},
|
|
30
|
+
"require": {
|
|
31
|
+
"types": "./dist/index.d.cts",
|
|
32
|
+
"default": "./dist/index.cjs"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"./package.json": "./package.json"
|
|
24
36
|
},
|
|
25
|
-
"main": "./dist/storyblok-js.js",
|
|
26
|
-
"module": "./dist/storyblok-js.mjs",
|
|
27
|
-
"types": "./dist/index.d.ts",
|
|
28
|
-
"files": [
|
|
29
|
-
"dist"
|
|
30
|
-
],
|
|
31
37
|
"dependencies": {
|
|
32
38
|
"@storyblok/preview-bridge": "^2.1.6",
|
|
33
|
-
"@storyblok/richtext": "5.
|
|
34
|
-
"storyblok-js-client": "7.7.
|
|
39
|
+
"@storyblok/richtext": "^5.3.0",
|
|
40
|
+
"storyblok-js-client": "^7.7.5"
|
|
35
41
|
},
|
|
36
42
|
"devDependencies": {
|
|
37
43
|
"@tsconfig/recommended": "^1.0.8",
|
|
38
44
|
"@types/node": "^24.11.0",
|
|
39
|
-
"@vitest/ui": "^
|
|
40
|
-
"cypress": "^
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"jsdom": "^26.0.0",
|
|
44
|
-
"kolorist": "^1.8.0",
|
|
45
|
+
"@vitest/ui": "^4.1.10",
|
|
46
|
+
"cypress": "^15.21.0",
|
|
47
|
+
"jsdom": "^27.1.0",
|
|
48
|
+
"oxlint": "1.76.0",
|
|
45
49
|
"pathe": "^2.0.3",
|
|
50
|
+
"publint": "^0.3.22",
|
|
46
51
|
"start-server-and-test": "^2.0.11",
|
|
47
|
-
"typescript": "
|
|
48
|
-
"vite": "^6.3
|
|
49
|
-
"vite-plugin-banner": "^0.8.0",
|
|
50
|
-
"vite-plugin-dts": "^4.5.3",
|
|
52
|
+
"typescript": "6.0.3",
|
|
53
|
+
"vite": "^6.4.3",
|
|
51
54
|
"vite-plugin-qrcode": "^0.2.4",
|
|
52
|
-
"vitest": "^
|
|
53
|
-
"@storyblok/
|
|
55
|
+
"vitest": "^4.1.10",
|
|
56
|
+
"@storyblok/lint-config": "0.1.0"
|
|
54
57
|
},
|
|
55
58
|
"release": {
|
|
56
59
|
"branches": [
|
|
@@ -64,18 +67,21 @@
|
|
|
64
67
|
]
|
|
65
68
|
},
|
|
66
69
|
"scripts": {
|
|
67
|
-
"dev": "
|
|
68
|
-
"build": "
|
|
70
|
+
"dev": "vp pack --watch",
|
|
71
|
+
"build": "vp pack",
|
|
69
72
|
"test:types": "tsc --noEmit --skipLibCheck",
|
|
70
73
|
"test": "pnpm run test:unit && pnpm run test:e2e",
|
|
71
|
-
"test:unit": "
|
|
72
|
-
"test:unit:ui": "vitest --ui",
|
|
74
|
+
"test:unit": "vp test run",
|
|
73
75
|
"test:e2e": "start-server-and-test cy:playground http://localhost:5173/ cy:run",
|
|
74
|
-
"test:e2e-watch": "start-server-and-test cy:playground http://localhost:5173/ cy:open",
|
|
75
76
|
"cy:playground": "pnpm --filter='./playground/vanilla' dev",
|
|
76
|
-
"lint": "
|
|
77
|
-
"lint:fix": "
|
|
77
|
+
"lint": "vp lint",
|
|
78
|
+
"lint:fix": "vp lint --fix",
|
|
79
|
+
"publint": "publint .",
|
|
78
80
|
"cy:run": "cypress run",
|
|
79
|
-
"cy:open": "cypress open"
|
|
81
|
+
"cy:open": "cypress open",
|
|
82
|
+
"test:watch": "vp test",
|
|
83
|
+
"test:ui": "vp test --ui",
|
|
84
|
+
"test:e2e:watch": "start-server-and-test cy:playground http://localhost:5173/ cy:open",
|
|
85
|
+
"test:coverage": "vp test run --coverage"
|
|
80
86
|
}
|
|
81
87
|
}
|
package/dist/api.d.ts
DELETED
package/dist/bridge.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const loadBridge: () => Promise<void>;
|