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