如何在Vue 3 SSR中动态设置JSON-LD?

huangapple go评论51阅读模式
英文:

how set dynamically jsonld in vue 3 ssr

问题

Here is the translated content you requested:

当我尝试通过组件 is='script' type='application/ld+json' 传递它时,出现错误:"TypeError: 无法将符号值转换为字符串",但当我通过 teleport 传递它时,只在客户端上工作。我使用 Laravel Inertia.js Vue 3 SSR。

我尝试在组件上使用 v-html
<component is='script' key='webSite' v-html='webSiteJSONLD' type='application/ld+json'></component> 但然后它只是像 script 标签内的 innerHTML 一样插入数据。

另一种方式会出现错误:"TypeError: 无法将符号值转换为字符串"
<component is='script' key='webSite' type='application/ld+json'>{{ webSiteJSONLD }}</component>

文本 JSON
const webSiteJSONLD = computed(() => {
return `{
'@context': 'https://schema.org',
'@type': 'WebSite',
'url': '${import.meta.env.SSR ? import.meta.env.VITE_APP_URL : host.value}'
}`;
});

英文:

When i try pass it by component is='script' type='application/ld+json' it has error:
"TypeError: Cannot convert a Symbol value to a string", but when i pass it by teleport it works but only on client. I use laravel inertiajs vue3 ssr

I tried to use v-html on component
<component is='script' key='webSite' v-html='webSiteJSONLD' type='application/ld+json'></component> but then it just insert data like attribute innerHTML in tag script.

in other way will be error: "TypeError: Cannot convert a Symbol value to a string"
<component is='script' key='webSite' type='application/ld+json'>{{ webSiteJSONLD }}</component>

text json
const webSiteJSONLD=computed(()=>{
return `{
'@context': 'https://schema.org',
'@type': 'WebSite',
'url': '${import.meta.env.SSR?import.meta.env.VITE_APP_URL:host.value}'
}`;
});

答案1

得分: 1

I made changes to the inertia.js fork head's component and modified the renderTag function in the component. It is functional, but there are some bugs.

我对惯性.js的分支头组件进行了更改,并修改了组件中的renderTag函数。它能够工作,但存在一些错误。

英文:

I writed fork head's component of inertia js and change function renderTag in component. And it works.But with bugs

renderTag(node) {
  // check specific symbol from node.type
  switch (node.type.toString()) {
    case 'Symbol(Text)':
    case 'Symbol(v-txt)':
      return node.children
    case 'Symbol()':
    case 'Symbol(Comment)':
      return ''
    // if nothing expected, return a html string
    default:
      return this.renderTagStart(node) + 
      (node.children ? this.renderTagChildren(node) : '') +
      (!this.isUnaryTag(node) ? `</${node.type}>` : '')
  }
}

答案2

得分: 0

创建一个新的组件:

mounted() {
    const myJsonScript = document.createElement('script');
    myJsonScript.setAttribute('type', 'application/ld+json');
    myJsonScript.setAttribute('src', '...src...');
    myJsonScript.setAttribute('id', 'random_id');
    document.getElementById('app').appendChild(myJsonScript);
}

beforeDestroy() {
    document.getElementById('random_id').remove();
}

在模板中为每个属性使用 props,然后它应该接近您的需求。

在纯SSR中,您可以在模板中这样做:

{{{ "<script type='application/ld+json'>" + value + "</script>" }}}
英文:

Create a new component with :

mounted () {

    const myJsonScript = document.createElement(&#39;script&#39;);
    myJsonScript.setAttribute(&#39;type&#39;, &#39;application/ld+json&#39;);
    myJsonScript.setAttribute(&#39;src&#39;, &#39;...src...&#39;);
    myJsonScript.setAttribute(&#39;id&#39;, &#39;random_id&#39;);
    document.getElementById(&#39;app&#39;).appendChild(myJsonScript)
}

beforeDestroy () {
    document.getElementById(&#39;random_id&#39;).remove()
}

Use props for each attributes, then it should be close to your need.

In pure SSR, you can do something like this in template:

{{{ &quot;&amp;lt;script type=&#39;application/ld+json&#39; &amp;gt;{&#39;key&#39;: &quot; + value + &quot;}&amp;lt;/script&amp;gt;&quot; }}}

huangapple
  • 本文由 发表于 2023年6月12日 15:08:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76454296.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定