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

[bug]: Cannot render in server component context #31

Open
AndreasBBS opened this issue Apr 6, 2024 · 5 comments
Open

[bug]: Cannot render in server component context #31

AndreasBBS opened this issue Apr 6, 2024 · 5 comments
Labels
issue: bug Issue reporting a bug

Comments

@AndreasBBS
Copy link

AndreasBBS commented Apr 6, 2024

What version of @strapi/blocks-react-renderer are you using?

npm: 9.8.1
node: 20.9.0
react: 18.2.0
next: 14.1.4
@strapi/blocks-react-renderer: 1.0.1
browser: any

What's Wrong?

I have a use case where I need to send the HTML on nodemailer. Strapi sends the result as JSON so I'm getting the HTML by using renderToStaticMarkup(<BlocksRenderer content={blocks}/>).
Unfortunately when I do this in Next 14 in a server action it throws an error.

To Reproduce

I made this codesandbox with a reproduction of the bug

Expected Behaviour

I expect to be able to render the BlocksRenderer component in the context of the server so that I can in turn use it to render the static markup.
I suspect that it has to do with the fact that BlocksRenderer has 'use client' and so Next 14 is probably skipping rendering in the context of the server. I don't wish to introduce a breaking change so I suggest making something like BlocksRendererPure without the 'use client' and the current BlocksRenderer expose as the BlocksRendererPure wrapped in a wrapper with the 'use client'.
If help is needed for a merge request let me know and I'll submit a fix according to whatever the package owner decides is the best way to fix this.

@AndreasBBS AndreasBBS added the issue: bug Issue reporting a bug label Apr 6, 2024
@AndreasBBS
Copy link
Author

@remidej Can I introduce a merge request with my proposed solution for this or do you think there's another way that's more proper? I've been waiting for some feedback on my propose solution to initiate a pull request.

@wzrdx
Copy link

wzrdx commented Aug 26, 2024

@remidej Can I introduce a merge request with my proposed solution for this or do you think there's another way that's more proper? I've been waiting for some feedback on my propose solution to initiate a pull request.

@AndreasBBS Can you please share your solution? I am trying to render the BlocksRenderer inside a Server component and I get a different error, but this might help me aswell.

@AndreasBBS
Copy link
Author

@remidej Can I introduce a merge request with my proposed solution for this or do you think there's another way that's more proper? I've been waiting for some feedback on my propose solution to initiate a pull request.

@AndreasBBS Can you please share your solution? I am trying to render the BlocksRenderer inside a Server component and I get a different error, but this might help me aswell.

This workaround is working for me.

But be warned that this forces you to send the content of the BlocksRenderer to the frontend where a sophisticated actor might capture it so make sure nothing sensitive or secret goes there.
I have not found a way to generate the markup all on the server side so far and doing it this way might pose security risks depending on the sensitivity of the content that is getting rendered using the BlocksRenderer.

@wzrdx
Copy link

wzrdx commented Aug 27, 2024

@remidej Can I introduce a merge request with my proposed solution for this or do you think there's another way that's more proper? I've been waiting for some feedback on my propose solution to initiate a pull request.

@AndreasBBS Can you please share your solution? I am trying to render the BlocksRenderer inside a Server component and I get a different error, but this might help me aswell.

This workaround is working for me.

But be warned that this forces you to send the content of the BlocksRenderer to the frontend where a sophisticated actor might capture it so make sure nothing sensitive or secret goes there. I have not found a way to generate the markup all on the server side so far and doing it this way might pose security risks depending on the sensitivity of the content that is getting rendered using the BlocksRenderer.

Thank you for sharing. I ended up downloading the source files, so I can change what I want. I am using NextJS with BlocksRenderer inside some server-side pages which are actually prerendered as static HTML during builds, so I'm not sure I understand your issue.

Just a suggestion, I don't know if it applies but it might be worth using an email service such as Brevo instead of nodemailer and sending custom emails from there :)

@AndreasBBS
Copy link
Author

@remidej Can I introduce a merge request with my proposed solution for this or do you think there's another way that's more proper? I've been waiting for some feedback on my propose solution to initiate a pull request.

@AndreasBBS Can you please share your solution? I am trying to render the BlocksRenderer inside a Server component and I get a different error, but this might help me aswell.

This workaround is working for me.

But be warned that this forces you to send the content of the BlocksRenderer to the frontend where a sophisticated actor might capture it so make sure nothing sensitive or secret goes there. I have not found a way to generate the markup all on the server side so far and doing it this way might pose security risks depending on the sensitivity of the content that is getting rendered using the BlocksRenderer.

Thank you for sharing. I ended up downloading the source files, so I can change what I want. I am using NextJS with BlocksRenderer inside some server-side pages which are actually prerendered as static HTML during builds, so I'm not sure I understand your issue.

Just a suggestion, I don't know if it applies but it might be worth using an email service such as Brevo instead of nodemailer and sending custom emails from there :)

Rendering a BlocksRenderer inside a server component should not be a problem because it is marked as 'use client' and NextJS should know to only render in the browser.
My case is that I'm trying to use specifically renderToStaticMarkup(<BlocksRenderer content={blocks}/>) inside a server-action to produce the static HTML that is going to be sent in the body of the email.
An option could be for me to be able to explicitly inform NextJS that I want to render an 'use client' component in the NextJS server context. As far as I know I there's no way to do this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
issue: bug Issue reporting a bug
Projects
None yet
Development

No branches or pull requests

2 participants