Symbols not populating references inside of them even If I use enrich, noTraverse and includeRefs

Please fill out as many of the following questions as possible so we can help you promptly! If you don’t know how to answer or it does not apply, feel free to remove it or leave it blank.

Builder content link
Footer Symbol: Builder.io: Visual Development Platform

Builder public api key
f127073fccdc44a590bf4362d8bb100b

Detailed steps to reproduce the bug
Basically I have a Footer which is a custom component that I converted into a Symbol so I can use it across different pages, it all worked great until I had to add a list of references to Card Icons (it’s a data model called asset that has a text field for a name and a file field for the icon image). Here’s an image of how it is shown in the visual editor:


And this is the part of the code I use to create that custom field when I registered the custom component (notice how I even try to set enrich and includeRefs there just to see if that would help):

Builder.registerComponent(Footer, {
  name: 'Footer',
  inputs: [
    {
      name: 'headingTag',
      type: 'string',
      defaultValue: 'h3',
      regex: {
        pattern: 'h[1-6]',
        message: 'Heading tag must be an h1, h2, h3, h4, h5, or h6',
      },
    },
    { name: 'showForm', type: 'boolean', defaultValue: true },
    {
      name: 'heroArtwork',
      friendlyName: 'Cellphone Artwork',
      type: 'file',
      allowedFileTypes: ['png', 'jpg', 'jpeg', 'svg'],
      required: true,
    },
    {
      name: 'cardIcons',
      type: 'list',
      required: false,
      defaultValue: [],
      subFields: [
        {
          name: 'cardIcon',
          type: 'reference',
          required: true,
          model: 'asset',
          options: {
            enrich: true,
            includeRefs: true,
          },
        },
      ],
    },
  ],
  noWrap: true,
})

The problem is that I’m using <BuilderComponent/> to render my whole homepage (and the rest of the pages I’ve created in builder visual editor) and when I use the Symbol in one of my pages I get an error of “Cannot read properties of undefined…” due to cardIcons not including the values (here’s an image using react devtools to show how data comes to the footer used in my homepage):


Notice how I only get the reference id and model but not the values.
Here’s how I use the Builder component in case I’m missing something:

<BuilderComponent
        model="page"
        options={{
          enrich: true,
          includeRefs: true,
          noTraverse: false,
          includeUnpublished: isDevEnv,
          cachebust: isDevEnv,
          cache: !isDevEnv,
        }}
        data={{
          archiveUrl: `/${finalArchiveUrl}/`,
        }}
      />

One important detail I have to mention is that I can fetch the data through graphql using enrich true and pass that data to the BuilderComponent through the content prop which is recommended and fix the issue, but gives me a huge amount of hydration errors with all the components (even the defaults that are from builder itself like the text component). This hydration errors are related with how builder apply binded styles (I have a data model with color values that I use in text components using the binding system), builder applies those binded styles through inline styles causing hydrations error messages like “Warning: Prop style did not match. Server: “null” Client: “color:rgba(35, 44, 51, 1)”” and since I don’t have a way to tell builder to not apply those values inline I can’t fix it. That’s why I can’t use the content prop approach

Code stack you are integrating Builder with
React and Gatsby

Given the detailed description of the problem and the context, it appears that what you need is a way to properly render the custom component with enriched data while avoiding hydration errors. Let’s address this step by step, considering both the registration and rendering layers.

Step 1: Ensure Proper Registration of Custom Component

It looks like your custom component Footer is registered correctly, but let’s double-check the implementation for completeness:

Custom Component Registration

import { Builder } from '@builder.io/react';
import Footer from './Footer'; // Ensure correct import

Builder.registerComponent(Footer, {
name: 'Footer',
inputs: [
{
name: 'headingTag',
type: 'string',
defaultValue: 'h3',
regex: {
pattern: 'h[1-6]',
message: 'Heading tag must be an h1, h2, h3, h4, h5, or h6',
},
},
{ name: 'showForm', type: 'boolean', defaultValue: true },
{
name: 'heroArtwork',
friendlyName: 'Cellphone Artwork',
type: 'file',
allowedFileTypes: ['png', 'jpg', 'jpeg', 'svg'],
required: true,
},
{
name: 'cardIcons',
type: 'list',
required: false,
defaultValue: [],
subFields: [
{
name: 'cardIcon',
type: 'reference',
required: true,
model: 'asset',
options: {
enrich: true,
includeRefs: true,
},
},
],
},
],
noWrap: true,
});

Step 2: Fetch Content with Enriched Data and Use the BuilderComponentYour current approach using <BuilderComponent /> makes use of options with enrich: true and includeRefs: true. However, let’s ensure that these options are set correctly:#### Fetching Content with EnrichmentFirst, make sure that the entry point (e.g., HomePage) fetches the enriched content properly:


javascript
import React from 'react';
import { builder, BuilderComponent } from '@builder.io/react';
builder.init('YOUR_PUBLIC_API_KEY');
const HomePage = () => {
return (

);
};
export default HomePage;

### Step 3: Debug Enriched Data

Make sure the `cardIcons` field in your data model includes the enriched data. You can do this by logging the content inside your `Footer` component to ensure it's received as expected:

```javascriptconst Footer = ({ headingTag, showForm, heroArtwork, cardIcons }) => { console.log('Card Icons:', cardIcons); return (
Cellphone Artwork {headingTag}
{showForm && ( {/* Form content */} )}
{cardIcons && cardIcons.map((iconRef, index) => (
{iconRef.cardIcon.data.name}
))}
);};

export default Footer; ```

Step 4: Handle Hydration Errors

Hydration errors often occur when the initial server-rendered HTML doesn’t match the client-rendered HTML. To mitigate this, ensure you handle conditional rendering or dynamic data fetching correctly.
A possible approach to solving hydration issues involves delaying client rendering until after hydration is complete. Here’s a small example using a React hook:

Delay Client Hydration

import React, { useEffect, useState } from 'react';import { BuilderComponent } from '@builder.io/react';const HomePage = () => {  const [hydrating, setHydrating] = useState(true);  useEffect(() => {    setHydrating(false);  }, []);  if (hydrating) {    return null; // Render nothing or a loading spinner  }  return (    <BuilderComponent      model="page"      options={{        enrich: true,        includeRefs: true,        noTraverse: false,        includeUnpublished: !process.env.NODE_ENV === 'production',        cachebust: !process.env.NODE_ENV === 'production',        cache: process.env.NODE_ENV === 'production',      }}    />  );};export default HomePage;

Final Steps

  1. Ensure Fetching Props: Verify that props like heroArtwork, cardIcons, and others are correctly fetched and passed down.

  2. Use React DevTools: Log props within your component and use React DevTools to inspect the current state and props received.

Conclusion

This approach ensures that your Footer component receives enriched data correctly and addresses potential hydration issues. If the problem persists, inspecting network requests, console logs, and React DevTools will help to identify discrepancies between server and client rendering.

If further issues arise, consulting Builder.io support with detailed logs and captured states from DevTools can provide more tailored assistance.

1 Like