3

I've built a blog website and am trying to implement dynamic social share cards for each individual blog. While everything appears to be working properly when I inspect the head element in developer tools, when I do a live test or run the link through social sharing preview tools (such as OpenGraph) my dynamic store variables are undefined.

I'm pulling the data from Supabase and saving it to a store. Here's the code that I'm using in my svelte:head tag:

<svelte:head>
    {#await $blogBeingViewed then blog}
        <title>Website - {blog.title}</title>
        <meta name="title" content="{blog.title}">
        <meta name="description" content="{blog.subtitle}">

        <!-- Open Graph / Facebook -->
        <meta property="og:type" content="website">
        <meta property="og:url" content="https://www.website.com/article/{blog.id}">
        <meta property="og:title" content="{blog.title}">
        <meta property="og:description" content="{blog.subtitle}">
        <meta property="og:image" content="{blog.image_url}">

        <!-- Twitter -->
        <meta name="twitter:card" content="summary_large_image">
        <meta name="twitter:url" content="https://www.website.com/article/{blog.id}">
        <meta name="twitter:title" content="{blog.title}">
        <meta name="twitter:description" content="{blog.subtitle}">
        <meta name="twitter:image" content="{blog.image_url}">
    {/await}
</svelte:head>

Any ideas why I'm experiencing this failure to properly populate my meta tags when attempting to share on social media?

I hope that I'm using the proper terminology (I'm just a hobbyist). Feel free to ask any follow-up questions that would help me to clarify my question.

Thank you for your time and assistance.

I've tried multiple variations on the code block shown above, i.e. without "#await," using "#if," etc.

jrfii
  • 41
  • 3
  • Are you using server-side rendering (ssr) or static side generation (ssg) ? When grabbing metadata (e.g. OpenGraph), crawlers don't always parse the javascript. They often only read the static html from the initial server response. The javascript created by Svelte needs to be parsed before those changes are reflected in the DOM. This is applies if you're not using SSR or SSG. If you are using SSR or SSG, it's probably a different issue. – Pete Mar 23 '23 at 01:32
  • Thanks for your response, Pete! I'm using SSR. It's strange to me that everything works properly in the browser, but not when sharing on social media or using a social share tool. If it's working properly in the browser, shouldn't it also work properly under other circumstances? – jrfii Mar 23 '23 at 01:43
  • No because it might just be a split second before the browser renders all the components, so what you see on the browser doesn't always represent the static HTML on the initial response. My guess would be that it's do with some kind of asynchronous task that's basically moving what would otherwise be rendered on the server to being rendered on the client. I'm not exactly sure of the nuance of that. There might be something in $blogBeingViewed that isn't properly SSR. What I would do is make that whole thing synchronous (remove {#await ...}), use dummy content instead, and see if it renders – Pete Mar 23 '23 at 05:55
  • Then work your way step by step until it stops working. Then hopefully you'll find the culprit. Maybe some kind of API call that isn't being done on the server or something. – Pete Mar 23 '23 at 05:56
  • 1
    @Pete, thank you for your assistance. I was able to figure out my error, as seen in my answer below. Your response likely put my thoughts on the right track; when I awoke this morning, the solution was in my head. I appreciate you taking the time to help me and others here on SO. – jrfii Mar 23 '23 at 21:47

1 Answers1

1

After sleeping on it, I realized that I needed to move my database logic from onMount to a +page.ts file. Data fetching done in an onMount function is not rendered on the server. By moving this logic to +page.ts, the data is fetched on the server and available when the page renders in the browser.

jrfii
  • 41
  • 3