Open andrelandgraf opened 2 years ago
Hi @andrelandgraf , thanks for the kind words and reporting this issue, the builderState
prop is passed to all registered custom components, so this is possibly related to what you have in the registerComponents
method, please share details of this method or a codesandbox/repo I can reproduce this issue on
Hi @teleaziz, thanks for your support!
Sure,registerComponents
:
import { Builder } from '@builder.io/react';
import { CallToActionLink } from '~/components/cta/callToActionLink';
import { StartBanner } from '~/components/start/start';
import { ButtonLink, TextLink, Image, H1, H2, H3, H4, Paragraph, ImageWithLink } from '~/components/UI';
import { getPublicBuilderInstance } from './builder';
let componentsHaveBeenRegistered = false;
export function registerComponents() {
if (componentsHaveBeenRegistered) {
return;
}
componentsHaveBeenRegistered = true;
// init builder
getPublicBuilderInstance();
Builder.registerComponent(ButtonLink, {
name: 'Button Link',
inputs: [
{ name: 'children', type: 'text', defaultValue: 'Button Text', required: true, friendlyName: 'Text' },
{ name: 'to', type: 'text', defaultValue: '/', required: true, friendlyName: 'Link' },
{ name: 'primary', type: 'boolean', defaultValue: false, friendlyName: 'Is Primary Button?' },
],
});
Builder.registerComponent(TextLink, {
name: 'Link in Text',
inputs: [
{ name: 'children', type: 'text', defaultValue: 'Link Text', required: true, friendlyName: 'Text' },
{ name: 'to', type: 'text', defaultValue: '/', required: true, friendlyName: 'Link' },
],
});
Builder.registerComponent(Image, {
name: 'Cloudinary Image',
inputs: [
{
name: 'src',
type: 'text',
defaultValue: 'https://res.cloudinary.com/...',
required: true,
},
{
name: 'alt',
type: 'text',
defaultValue: '...',
required: true,
},
{
name: 'width',
type: 'text',
defaultValue: 'auto',
enum: ['auto', 'max'],
},
],
});
Builder.registerComponent(ImageWithLink, {
name: 'Cloudinary Image with Link',
inputs: [
{
name: 'src',
type: 'text',
defaultValue: 'https://res.cloudinary.com/...',
required: true,
},
{
name: 'alt',
type: 'text',
defaultValue: '...',
required: true,
},
{
name: 'width',
type: 'text',
defaultValue: 'auto',
enum: ['auto', 'max'],
},
{
name: 'ariaLabel',
type: 'text',
defaultValue: 'Link Label',
required: true,
friendlyName: 'Aria Label',
},
{ name: 'to', type: 'text', defaultValue: '/', required: true, friendlyName: 'Link' },
{ name: 'withShadow', type: 'boolean', defaultValue: true, friendlyName: 'Background Shadow' },
],
});
Builder.registerComponent(H1, {
name: 'Heading 1',
inputs: [
{ name: 'children', type: 'text', defaultValue: 'Heading 1', required: true, friendlyName: 'Text' },
{ name: 'asH2', type: 'boolean', defaultValue: false, friendlyName: 'Als Heading 2' },
],
});
Builder.registerComponent(H2, {
name: 'Heading 2',
inputs: [{ name: 'children', type: 'text', defaultValue: 'Heading 2', required: true, friendlyName: 'Text' }],
});
Builder.registerComponent(H3, {
name: 'Heading 3',
inputs: [{ name: 'children', type: 'text', defaultValue: 'Heading 3', required: true, friendlyName: 'Text' }],
});
Builder.registerComponent(H4, {
name: 'Heading 4',
inputs: [{ name: 'children', type: 'text', defaultValue: 'Heading 4', required: true, friendlyName: 'Text' }],
});
Builder.registerComponent(StartBanner, {
name: 'StartBanner',
inputs: [],
});
Builder.registerComponent(CallToActionLink, {
name: 'CallToActionLink',
inputs: [],
});
// overrides Text builder basics component
Builder.registerComponent(Paragraph, {
name: 'Text',
inputs: [
{
name: 'children',
type: 'richText',
defaultValue: '<b>Paragraph Text</b>',
required: true,
friendlyName: 'Text',
},
{
name: 'parseAsHTML',
type: 'boolean',
defaultValue: true,
showIf: () => false,
},
{
name: 'As',
type: 'text',
defaultValue: 'div',
showIf: () => false,
},
],
});
Builder.registerComponent(Paragraph, {
name: 'Paragraph',
inputs: [
{
name: 'children',
type: 'richText',
defaultValue: '<b>Paragraph Text</b>',
required: true,
friendlyName: 'Text',
},
{
name: 'parseAsHTML',
type: 'boolean',
defaultValue: true,
showIf: () => false,
},
{
name: 'As',
type: 'text',
defaultValue: 'div',
showIf: () => false,
},
],
});
}
And getPublicBuilderInstance
:
let isInitialized = false;
export function getPublicBuilderInstance() {
if (!isInitialized) {
isInitialized = true;
// init builder page rendering with public key
builder.init('...');
}
return builder;
}
We're seeing the same issues, on the same stack. Hydrogen v2 (Remix) and React 18, after a mismatch and hydration builder's css gone and the page is broken. Any idea how this can be fixed?
Facing same issue. Hydration error for custom components. Server content not matching with client. Any fix??
Hey friends! Big fan of builder! I am running into an issue with builder and React 18. I am using Remix and Tailwind but I am very certain that it's React 18 that is causing the issue.
Describe the bug
React throws the following error when builder is used with React 18 and server-side rendering:
Warning: React does not recognize the
builderStateprop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase
builderstateinstead. If you accidentally passed it from a parent component, remove it from the DOM element.
The server-side rendered HTML loads fine (builder page looks as expected and builder style tags present). After hydration, React reports:
Hydration failed because the initial UI does not match what was rendered on the server.
Then the builder pages lose their styling (the emotion style tags disappear).To Reproduce
Steps to reproduce the behavior:
hydrateRoot
My (Remix.run) client entry file:
Expected behavior
Builder works as expected after React hydration and doesn't loose the CSS properties.
The following non-React 18 client entry file works:
Additional context