Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support React Server Components and Next app router #1201

Merged
merged 10 commits into from
Nov 4, 2024

Conversation

edodusi
Copy link
Contributor

@edodusi edodusi commented Aug 26, 2024

This proposal aims to solve #952 by reorganizing the exports that we have in our react/rsc module and making a slightly impactful change on the storyblokInit() function.

By copying the StoryblokComponent and Story components in the rsc module we are creating a boundary between the rsc and the rest, ensuring proper isolation. Ideally we don't want to have duplicated code and this would need some refactoring in the future.

The most significant change is in the storyblokInit() function, which now instead of just setting the global storyblokApi variable is returning it. This is because if we rely on side effects only for useStoryblokApi() we may fall into race conditions, especially in RSC where the context is not shared between client and server and we don't have a state, every new component is rendered from scratch and storyblokApi could be uninitialized.

So for every new render, client or server, if we have the storyblokApi initialized then we can return it, otherwise we need a new server side call to initialize it.

This results in a small change for the clients implementing this SDK: storyblokInit() now returns the API object that components need to fetch data.

Here's an example of a client implementation.

// lib/storyblok.ts

import Page from '@/components/Page';
import Teaser from '@/components/Teaser';
import { apiPlugin, storyblokInit } from '@storyblok/react/rsc';

export const getStoryblokApi = storyblokInit({
  accessToken: 'API_TOKEN',
  use: [apiPlugin],
  components: {
    teaser: Teaser,
    page: Page,
  },
});

And in components:

// app/home/component.ts

import { getStoryblokApi } from '@/lib/storyblok';

export default async function Component() {
  const { data } = await fetchData();
  
  // ...
}

export async function fetchData() {
  let sbParams: ISbStoriesParams = { version: 'draft' };

  const storyblokApi: StoryblokClient = getStoryblokApi();
  return storyblokApi.get(`cdn/stories/home`, sbParams);
}

This should not affect existing implementations. Follow the updated README for the rest of the implementation.

This would require to update the documentation on the RSC part.

@edodusi edodusi marked this pull request as draft August 26, 2024 13:06
@edodusi edodusi marked this pull request as ready for review August 27, 2024 07:20
@edodusi edodusi force-pushed the feat/next-rsc-support branch 2 times, most recently from eeaaa6a to a120768 Compare October 9, 2024 13:17
Copy link

pkg-pr-new bot commented Oct 9, 2024

Open in Stackblitz

yarn add https://pkg.pr.new/@storyblok/[email protected]

commit: 23ecad3

lib/rsc/index.ts Outdated Show resolved Hide resolved
Copy link
Contributor

@alvarosabu alvarosabu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will continue checking, this is only the review for this commit

lib/rsc/story.tsx Outdated Show resolved Hide resolved
lib/rsc/story.tsx Show resolved Hide resolved
lib/rsc/story.tsx Outdated Show resolved Hide resolved
lib/rsc/storyblok-component.tsx Outdated Show resolved Hide resolved
Copy link
Contributor

@alexjoverm alexjoverm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a few commments from my side Edo!

README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
playground-next13-rsc/app/page.tsx Outdated Show resolved Hide resolved
@edodusi edodusi self-assigned this Oct 14, 2024
@edodusi edodusi added the breaking-change Changes that cause backward compatibility issues and will require a major version. label Oct 14, 2024
@alvarosabu alvarosabu requested review from arorachakit, dipankarmaikap and alexjoverm and removed request for alexjoverm October 17, 2024 06:23
alvarosabu
alvarosabu previously approved these changes Oct 17, 2024
BREAKING CHANGE: components renamed and `storyblokInit` returns the API
instance
@alvarosabu alvarosabu self-requested a review November 4, 2024 08:54
@alvarosabu alvarosabu requested review from alexjoverm and removed request for alexjoverm November 4, 2024 08:58
@edodusi edodusi dismissed alexjoverm’s stale review November 4, 2024 09:04

comments are solved

@alvarosabu alvarosabu merged commit 9ea0532 into main Nov 4, 2024
5 checks passed
Copy link
Contributor

github-actions bot commented Nov 4, 2024

🎉 This PR is included in version 4.0.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking-change Changes that cause backward compatibility issues and will require a major version. released
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants