Dynamic bindings not working on load in production

Element data bindings don’t seem to work on load for my header section in production, https://www.buildquick.dev. I have several bindings for various styles and none of them are applied on first load:

In the screenshot above, the header text should have a blue color and the header should have a drop shadow, like this:

The bindings typically take the form of something like export default state.isScrolled ? "white" : "blue". isScrolled and other state variables are set and updated within my header section’s custom JS. Here’s mine:

function updateIsScrolled() {
  if (window.scrollY > 50) {
    state.isScrolled = true;
  } else {
    state.isScrolled = false;
  }
}

async function main () {
  if (Builder.isServer) {
    state.isMobileMenuOpen = false;
    state.isScrolled = false;
  }

  if (Builder.isBrowser) {
    state.isMobileMenuOpen = false;
    updateIsScrolled();

    window.addEventListener("scroll", () => {
      updateIsScrolled();
    })
  }
}

export default main();

The scroll listener in my custom JS triggers an update to state once you start scrolling, at which the correct styles are applied, but I don’t think the issue has to do with state being set/unset. First of all, state should be set within the Builder.isServer block, and second, the bindings that evaluate state properties should evaluate undefined properties as falsy and still set the correct value for their associated styles.

No errors in the JS console.

Also, everything works as expected on my local development server (Next.js) and within the Visual Editor.

Any idea what’s going on?

Hey @ersin ! Hmm this is interesting, it seems for some reason the default value isn’t being set…I will have to investigate further

There are a few ways to get around around it in the meantime though

First, you can delay the rendering of the component until browser load by giving a data binding to Show if only if Builder.isBrowser, like below:
Screen Shot 2022-08-03 at 4.46.29 PM

This will delay render until the browser and run any logic upon client-side render. The draw back with this approach is that you will lose any server side rendering on that particular component.

Another option is to set the default styling manually. You can set a default style BEFORE you set the data binding, which will the show up before any data binding logic runs. OR you could just manually enter it in the JSON view of the component by hitting command+E and manually adding the styles there

Screen Shot 2022-08-03 at 4.48.30 PM

Hope this helps!

Great, thanks for the workarounds, @TimG! Do let me know if y’all diagnose the root cause.

@TimG did y’all ever find the root cause of this issue? I’m still using the isBrowser hack to get my page to render correctly.

Hey @ersin apologies for delayed response here. Based on the title, is this only happening in production? And not on your local?

If so, I wonder if using this approach might help clean up the issue:

Hi @TimG! Thanks, this worked!

But what’s going on behind the scenes? I’m just hosting on Vercel with Next.js, very standard setup for Builder. Are you recommending this fix for all customers moving forward?

Essentially there is a library we use for data bindings on the server, and for some reason vercel, netlify and other platforms either remove or are not compatible with this library when deploying to production. So the code snippet provided explicitly adds in the library when needed.

As to is this recommended going forward, hopefully no! This is our work around for now, the plan is to implement this fix natively within our SDK so hopefully it wont be a workaround for much longer !

1 Like