feat(react): new react SDK - #665
Draft
dipankarmaikap wants to merge 49 commits into
Draft
Conversation
- Remove rollupTypes which doesn't work with nested entry points
- Remove preserveModules which leaked internal workspace paths
- Add fixDtsExports plugin to remove erroneous 'export {}' from .d.ts files
## Summary
Updates Angular environment file handling in the `create` command to use
simple string replacement for placeholders instead of regex-based value
matching.
## Changes
- Add `updateAngularEnvironmentFiles` function for Angular-specific
environment file handling
- Pass `template` parameter to `handleEnvFileCreation` to detect Angular
projects
- Use `replaceAll` to replace `STORYBLOK_DELIVERY_API_TOKEN` and
`STORYBLOK_REGION` placeholders with actual values
## Before
The Angular environment files kept the placeholder names as literal
strings.
## After
```ts
// environment.ts
export const environment = {
production: true,
accessToken: 'actual-token-here', // Replace with your Storyblok Delivery API token
region: 'eu', // Replace with your Storyblok region
};
```
## Related
Works with the Angular blueprint update:
storyblok/blueprint-core-angular#18
This reverts commit 5f61c7d.
- Export v2 SDK as @storyblok/react/next, /next/rsc, /next/client - Remove rollupTypes (incompatible with nested entries) - Remove preserveModules (leaked workspace paths) - Keep source in src/v2/, export as /next for experimentation
@storyblok/angular
@storyblok/astro
@storyblok/api-client
storyblok
@storyblok/eslint-config
@storyblok/js
storyblok-js-client
@storyblok/live-preview
@storyblok/management-api-client
@storyblok/migrations
@storyblok/nuxt
@storyblok/react
@storyblok/region-helper
@storyblok/richtext
@storyblok/svelte
@storyblok/vue
commit: |
…#672) Assets migrated between spaces with `storyblok assets push` lost the `<width>x<height>` dimensions folder in their CDN URL (e.g. `.../f/SPACE/2048x1820/hash/image.jpg` became `.../f/SPACE/hash/image.jpg`), even when the source asset had it. Root cause: Storyblok's backend only appends the dimensions folder to the S3 key when the sign request (`POST /v1/spaces/{id}/assets`) includes a `size` field — it does not derive it from the actual image. Two gaps combined to drop it: - `@storyblok/management-api-client`'s `assets.create()` explicitly whitelisted only `short_filename`, `asset_folder_id`, `is_private` when calling `upload()`, silently discarding `size` (and `validate_upload`) even though both are part of its declared input type. - The CLI's `assets push` never derived a `size` for pushed assets in the first place. ## Changes - `packages/mapi-client/src/resources/assets.ts`: `create()` now forwards `size`/`validate_upload` to the sign request. - `packages/cli/src/commands/assets/streams.ts`: when creating a pushed asset, reuse the dimensions already present in the source asset's filename URL (parsed via a new `extractAssetSizeFromFilename` helper) so pushed assets keep them. - Added regression tests in both packages. Fixes WDX-480
- Add ComponentEntry type for component config with fallback options - Auto-detect React.lazy components and wrap in Suspense - Add per-component fallback option for custom loading states - Add global suspenseFallback config for default loading UI - Add suspense option to force Suspense wrapping for async components
- project: @storyblok/api-client 0.4.0 - project: @storyblok/management-api-client 0.4.0 - project: @storyblok/migrations 0.1.17 - project: @storyblok/angular 1.0.2 - project: @storyblok/openapi 2.1.0 - project: storyblok 4.18.3
This PR fixes the TDZ (`ReferenceError`) caused by circular dependencies when Storyblok components are imported directly and also render `<StoryblokComponent />` internally. It also adds both unit and Cypress tests to cover this scenario and help prevent future regressions. Fixes #547.
#630) Teaches the `storyblok` CLI to push and pull assets to either a space or the organization's shared libraries, so both kinds round-trip. A library is a top-level shared asset folder with per-space read or write access. ## How **mapi-client (`@storyblok/management-api-client`)** - Adds three hand-written shared resources, mirroring the WDX-409 `convertToShared` pattern (these endpoints are not in the generated SDK, since the WDX-407 overlay will not land): `sharedAssetFolders`, `sharedAssets` (full sign → S3 → finish → get upload flow), and `sharedInternalTags` (every call carries `asset_folder_id` = library root). - Exports the existing `uploadToS3` helper for reuse. - Endpoint request/response shapes were verified against `../storyrails` before wiring. **CLI (`storyblok`)** - `scope.ts`: a `Scope` discriminated union (`space` | `library`), on-disk base-dir resolution, library listing and access helpers, read-only failfast, and a library-root resolver. The existing transport-injected pipelines are reused unchanged. - `assets push`: `--target <space|shared|all>` and `--library` flags, a scope loop, read-only-library failfast (no partial state), and library tag remap (`internal_tag_ids` are mapped to the library's shared tags, creating any that are missing). `meta_data` round-trips. Shared-asset creates default the folder to the library root, and the library root folder is skipped on bulk push (it is a shared root folder that cannot be pushed from a space). - `assets pull`: `--target <with-referenced|all|space|shared>` (default `with-referenced`), which pulls space assets and then resolves shared-library assets referenced by already-pulled local stories. Classification is id-based, never URL-prefix-based. - `--target` is constrained with Commander `.choices()`, so unknown values fail fast with a non-zero exit. - Shared `shared_*` API error actions; command READMEs updated. ## On-disk layout Library assets live under `.storyblok/assets/shared/<library_id>/`, parallel to the space subtree at `.storyblok/assets/<space_id>/`, each with its own `manifest.jsonl`. Fixes WDX-408
Rename the previous Linear ticket prefix `WDX` to the new `DX` prefix across the repository. ## Changes - Ticket references (`WDX-123` → `DX-123`) in agent skills (`investigate`, `spec`, `triage`), `.claude/rules/artifact-naming.md`, `AGENTS.md` (branch naming + commit footer conventions), and `adr/0004`. - Linear team key in `linear-fetch.sh`: `DEFAULT_TEAM` and `--team` references (`WDX` → `DX`). The ticket prefix is the Linear team key, so leaving the default would break the `triage` command. ## Left untouched (intentional) - `storyblok/openapi-wdx` repository name and the `openapi-wdx-` temp-dir prefix in `tools/openapi-codegen/` — a real GitHub repo name, not a ticket reference.
…DX-273) (#675) Adds selective sync to `components pull` and `components push` so teams sharing a single space can sync only their own components. - `components pull` gains `--filter <glob>`, `--group <name|Parent/Child path>` (repeatable, includes descendant groups), and `--tag <name>` (repeatable, comma-separated). - `components push` gains `--group` and `--tag` with the same semantics. - Selectors combine with AND across types and OR within a repeatable selector. `--filter` is a `minimatch` glob applied on top. Fixes DX-273
…ck (#691) Adds `packages/js-client/vitest.config.ts` enabling Vitest `typecheck` so `vitest run` collects and type-checks `src/**/*.test-d.ts`. ## Why Follow-up to #677 (DX-472). That PR added `src/index.test-d.ts` with `expectTypeOf` assertions pinning the write methods (`post`/`put`/`patch`/`delete`) to `ISbResponse`, and described them as enforced by both `test:types` (tsc) and `vitest --typecheck`. In reality only `test:types` enforced them: - There was no `vitest.config.ts`, and `test:unit` is a plain `vitest run` with no `--typecheck` flag. - Vitest's default `include` matches `*.{test,spec}.ts` — it never matches `*.test-d.ts`, so the file wasn't even collected by `vitest run`. Fixes DX-472
- Remove rollupTypes which doesn't work with nested entry points
- Remove preserveModules which leaked internal workspace paths
- Add fixDtsExports plugin to remove erroneous 'export {}' from .d.ts files
This reverts commit 5f61c7d.
- Export v2 SDK as @storyblok/react/next, /next/rsc, /next/client - Remove rollupTypes (incompatible with nested entries) - Remove preserveModules (leaked workspace paths) - Keep source in src/v2/, export as /next for experimentation
- Add ComponentEntry type for component config with fallback options - Auto-detect React.lazy components and wrap in Suspense - Add per-component fallback option for custom loading states - Add global suspenseFallback config for default loading UI - Add suspense option to force Suspense wrapping for async components
…monoblok into feature/new-react-sdk
Contributor
|
…mponent types - Add `StoryblokComponentProps<T>` helper interface to simplify typing blok components - Introduce `AnyBlokComponent` internal type to avoid contravariance errors when registering components with specific blok shapes - Export `ComponentEntry`, `RegistryConfig`, and `RegistryResult` types from v2 index
…reaming Passing async Server Component output as initialContent prop + useState forced the RSC serializer to fully await all async components before sending the payload, bypassing Suspense boundaries and blocking the initial page response (TTFB) for the full duration of any slow async component. Using children keeps the RSC subtree in the server stream where Suspense works correctly. The component now tracks editor updates in a separate updatedContent state (null until the first editor event), rendering updatedContent ?? children. Also fix pre-existing lint errors in guide.md (one-liner if statements, Unicode ellipsis in code block, missing braces).
Without debouncing, every editor keystroke fires a Server Action call. If the component tree contains a slow async Server Component (e.g. an external API fetch), each keystroke can trigger a redundant 10-second request — and if the user edits a field that is part of the cache key (e.g. a location name), each intermediate value starts its own fetch. Add a debounceMs prop (default 300 ms) that cancels the pending re- render timer on each new editor event and only fires the Server Action after the user pauses. The timer is cleared on unmount so no stale updates can arrive after the component is removed.
- Bump install snippet to fc8fac6 (latest) - Section 2: update page.tsx example to use children syntax - Section 4: full rewrite documenting children prop, debounceMs prop, and the reasoning behind each — why children preserves RSC streaming (named prop + useState forces the serialiser to await all async components, bypassing Suspense) and why debounce avoids firing a Server Action on every keystroke - Section 5: expand caching table from 3 to 4 layers (add LRUCache and inFlightDraftFetches rows); update code example to reflect the lru-cache implementation with TTL + max-size cap
…kBlocks to resolved components
…yblokPreview Previously the Suspense fallback was always `children` (the original SSR snapshot). After a first renderContent call resolved and the user made a second edit, the page would jump back to stale content while the new render was in flight. Fix: add `fallback` state (starts as `children`) and advance it via an onCommit callback in LiveContent each time use(promise) resolves. Subsequent editor updates now show the most-recently committed content as the fallback instead of reverting to the original SSR tree.
… RSC streaming Storing `children` in useState forces the RSC serialiser to fully await every async component in the subtree before committing the initial state value. With a component like WeatherWidget (10 s fetch) in the tree this blocked the entire initial HTML response, causing a blank page for the full duration of the slowest component — exactly what useState<ReactNode> does according to the guide. Fix: initialise committedContent to null instead of children. The Suspense fallback now uses `committedContent ?? children`: - Before the first renderContent resolves: children is read directly from the prop (never from state), keeping it inside React's RSC streaming channel so Suspense boundaries fire normally. - After the first renderContent resolves: committedContent holds the server-rendered output (fully resolved, safe in state). Subsequent editor updates show the latest committed state as the fallback instead of reverting to the original SSR snapshot.
…d playground link - Bump install URL to pkg.pr.new/@storyblok/reacta76b1c7 - Add playground repo link (dipankarmaikap/nextjs-storyblok-react-sdk-v2) - Replace draftMode() cookie approach with two-deployment isPreview strategy (STORYBLOK_ENV=preview env var; network-first cache on preview deployment) - Rewrite page rendering section: catch-all [[...slug]] route, Next.js 16 async params pattern, StoryContent single-source-of-truth component - Simplify WeatherWidget caching: remove LRU + inFlightDraftFetches draft path; use unstable_cache on both deployments (weather is external/independent)
This was referenced Aug 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.