Server errors Vue - Nuxt3 / Builder io

Hello,

I have a problem using data binding and I feel i’m missing something. First of all i have a page with builder configuration like this :

<script setup>
import PUBLICAPI from "@/api/public"
import { Content, fetchOneEntry, isPreviewing } from "@builder.io/sdk-vue"
import REGISTERED_COMPONENTS from "@/components/builderCustomComponents"

const { $appHashedApiKey } = useNuxtApp()
const route = useRoute()
const runtimeConfig = useRuntimeConfig()
const apiKey = runtimeConfig.public.PublicBuilderApiKey

const canShowContent = ref(false)
const model = "public-page"
const builderContent = ref(null)

const { data: content } = await useAsyncData("builderData", () =>
  fetchOneEntry({
    model,
    apiKey,
    userAttributes: {
      urlPath: route.path,
    },
  })
)

canShowContent.value = content.value ? true : isPreviewing(route.path)

const urlParams = route.path.split("/").filter(Boolean).pop()
let urlQueries = route.query

const apiInstances = []

async function init_data(content) {
  const pageData = content.data.pageData

  const queries = pageData.map((elm, idx) => {
    const publicapi = new PUBLICAPI(
      elm.data,
      elm.service,
      urlParams,
      urlQueries,
      $appHashedApiKey
    )

    const requestName = `${elm.service}_${idx}`
    apiInstances.push({
      name: requestName,
      api: publicapi,
    })

    return {
      name: requestName,
      query: publicapi.fetchDataSSR(),
    }
  })

  return executeQueries(queries)
}

async function executeQueries(queries) {
  const results = await Promise.all(queries.map((q) => q.query))

  const formattedResults = queries.reduce((acc, query, idx) => {
    acc[query.name] = results[idx]
    return acc
  }, {})

  return formattedResults
}

const toSend = ref(await init_data(content.value))

watch(
  () => route.query,
  // Restrict to catalog page only ?
  async (newQueries) => {
    const queries = apiInstances.map((elm) => {
      elm.api.data.url_queries = newQueries
      return {
        name: elm.name,
        query: elm.api.fetchDataClient(),
      }
    })

    toSend.value = await executeQueries(queries)
  }
)

if (content.value.data.meta) {
  useSeoMeta({
    title: content.value.data.meta.title,
    ogTitle: content.value.data.meta.ogTitle,
    description: content.value.data.meta.description,
    ogDescription: content.value.data.meta.ogDescription,
    ogType: content.value.data.meta.ogType,
    ogImageUrl: content.value.data.meta.ogImageUrl,
    ogImageAlt: content.value.data.meta.ogImageAlt,
    twitterCard: content.value.data.meta.twitterCard,
    ogUrl: content.value.data.meta.ogUrl,
  })
}
</script>

<template>
  <div v-if="canShowContent" ref="builderContent">
    <Content
      :key="JSON.stringify(toSend)"
      :api-key="apiKey"
      :model="model"
      :content="content"
      :data="toSend"
      :custom-components="REGISTERED_COMPONENTS"
    />
  </div>
</template>

Where toSend is some data i send to binding to builder. I can see it in the builder content state

And i’m using binding on a builder text component like this :

But i get this error :

[Builder.io]:  Failed code evaluation: Property is getter {code: 'var _virtual_index=state.GET_CATALOG_0.filters.sub_categories.length<0;return _virtual_index'} 
  at Object.error (node_modules/@builder.io/sdk-vue/lib/node/should-force-browser-runtime-in-node-ikxWrCvn.js)
  at J (node_modules/@builder.io/sdk-vue/lib/node/index-dZfvXbI_.js)
  at Gt (node_modules/@builder.io/sdk-vue/lib/node/index-dZfvXbI_.js)

I can add Builder.isBrowser but i get Hydratation Mismatch in this case. I feel JS is not executed on server side.

I work on local and when i do :

/*
  * Global objects available:
  *
  * state - builder state object - learn about state https://www.builder.io/c/docs/guides/state-and-actions
  * context - builder context object - learn about state https://github.com/BuilderIO/builder/tree/main/packages/react#passing-data-and-functions-down
  * fetch - Fetch API - https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API'
  * Builder - Builder object - useful values include: Builder.isServer, Builder.isBrowser, Builder.isPreviewing, Builder.isEditing
  *
  * visit https://www.builder.io/c/docs/guides/custom-code
  * for more information on writing custom code
  */
 async function main () {

  if (Builder.isEditing || Builder.isServer) {
    console.log('1', state)
    // Place any code here you want to only run on the server. Any  
    // data fetched on the server will be available to re-hydrate on the client
    // if added to the state object
  }

  if (Builder.isBrowser) {
    console.log('2', state)
    // Place code that you only want to run in the browser (client side only) here
    // For example, anything that uses document/window access or DOM manipulation
  }
}

export default main();

Client is logged but served is not. I’m sure i have activated SSR in my project and I use

@builder.io/sdk-vue": "^3.0.1". And isServer is false on client side and nothing is logged in server console logs.

My nuxt configuration :

export default defineNuxtConfig({
  compatibilityDate: "2024-11-01",
  devtools: { enabled: true },
  modules: ["vuetify-nuxt-module"],
  ssr: true,
  css: ["~/assets/style.scss"],
  vite: {
    css: {
      preprocessorOptions: {
        scss: {
          api: "modern-compiler",
        },
      },
    },
  },
  runtimeConfig: {
    public: {
      PublicBuilderApiKey: process.env.PUBLIC_BUILDER_API_KEY,
      apiSecretKey: process.env.NUXT_PUBLIC_API_SECRET_KEY,
    },
  },
})

I don’t understand,

Please help,

Many Thanks

1 Like