Issue binding some html attribute

Hi,
I’m facing an issue when i try to bind html attributes for example here :


When I publish it, I only see empty parameters in the html, no dynamic data

Hey @Guimic , could you please provide me with the Builder Content Entry link where you’re experiencing an issue as it this will me further my investigation?

Here is how to find it:

Hi Sheema,
Sure :slight_smile:
here is the content link : Builder.io: Visual Development Platform

And you can preview it with the following preview link (to bind data) : https://develop.d1gxapjes09rnx.amplifyapp.com/test/42b5b50b-a6a7-4260-9026-337415bf30ea

Apparently, it seems to be the same issue than this old ticket (if it can help you to investigate): Issue Binding HTML Attributes

Hey @Guimic could you please clarify your data binding on your page? I don’t see any content inputs or data connected to your page.

add the following url in the preview field to retreive data https://develop.d1gxapjes09rnx.amplifyapp.com/test/42b5b50b-a6a7-4260-9026-337415bf30ea

Did you manage to reproduce the bug?

Hi @sheema,
Do you have an update to share :slight_smile: ?

Hey @Guimic, I have not been able to replicate this. This looks like an integration issue. Could you please share your integration code with me to investigate this further?

Hi Sheema,
Here is a detailed example :

  1. You can use this buidler element to replicate it : Builder.io: Visual Development Platform
    or create a new empty page - (Content state is empty in this case)
  2. Add a text element in the page
  3. Change preview URL to retrieve data in the state (use https://develop.d1gxapjes09rnx.amplifyapp.com/test/42b5b50b-a6a7-4260-9026-337415bf30ea for example)
  4. At this time content state changed
    Screenshot of the state at this step :
  5. Now bind text element on the state data. For example let’s bind the text content on the color name and repeat it for each color
    Repeat for each : state.GET_VARIANT_0.properties.colors
    Text content binding : state.colorsItem.value
    Screenshot :
  6. At this step everything is ok ! I can publish it and see a live page with 4 colors name
  7. Now I try to bind an html attribute. Let’s bind the name properties on the same as text content (state.colorsItem.value)
    Screenshots :

  8. Now I inspect the live page and despite I see the new name attribute in the html, I don’t have the binded color value
    Screenshot

Is it more undestandable now ?
We can schedule a call to show you if you prefer

Hey @Guimic , I need the code for the integration that shows how you are integrating Builder with your App. I am clear with the steps you have provided.

Here it is

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

const { $appHashedApiKey, $eventBus } = 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 api = new API(
      elm.data,
      elm.service,
      urlParams,
      urlQueries,
      $appHashedApiKey
    )

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

    return {
      name: requestName,
      query: api.client ? api.fetchDataAmplify() : api.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.client
          ? elm.api.fetchDataAmplify()
          : elm.api.fetchDataClient(),
      }
    })

    toSend.value = await executeQueries(queries)
  }
)

$eventBus.on("onChangeLocalStorage", async () => {
  const queries = apiInstances.map((elm) => {
    elm.api.data[elm.api.localStorageName] =
      localStorage.getItem(elm.api.localStorageName) || JSON.stringify([])

    return {
      name: elm.name,
      query: elm.api.client
        ? elm.api.fetchDataAmplify()
        : elm.api.fetchDataClient(),
    }
  })

  toSend.value = await executeQueries(queries)
})

$eventBus.on("onAuthChanges", async (data) => {
  if ("status" in data) toSend.value.auth_status = data.status
  if (data.email) toSend.value.email = data.email
})

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,
  })
}

onMounted(() => {
  const links = builderContent.value?.querySelectorAll("a")

  if (links) {
    links.forEach((link) => {
      const href = link.getAttribute("href")
      const isInternalLink = link.getAttribute("data-internal-link") !== "false"
      const isBlankTarget = link.getAttribute("target") === "_blank"

      if (isInternalLink && !isBlankTarget) {
        link.addEventListener("click", (event) => {
          if (event.metaKey || event.ctrlKey || event.button !== 0) return
          event.preventDefault()
          if (href) {
            navigateTo(href)
          }
        })
      }
    })
  }
})
</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>

Hi @sheema
I just figured out this is the same for img as well, and for all binded html attributes in reality

Hello @Guimic,

I wanted to update you that we’ve successfully reproduced the issue on our end related to the dynamic binding of HTML attributes. We’re currently discussing it internally to determine the next steps. Rest assured, I’ll keep you updated as soon as we make any progress.

Thanks,

Hi @manish-sharma any news to share ?

Hi @Guimic,

We’re still working on the fix and I’ll be sure to keep you updated as soon as there’s progress.

Thank you for your patience and understanding.

Best regards,