Google Trends in Vue & Nuxt.JS

I've been doing a fair amount of work in Nuxt.JS of late. I'd previously used Next.JS but found React not to my liking and that Vue just fit better with my mental model/workflow.

While they are great for accelerating development there are definitely some areas where it's made things a little trickier. One such area is when you wish to drop some "simple" client-side JavaScript in - here's the process I went through to get Google Trends to work.

It looks like this:

The errors

Google Trends is a great way of visualizing what trends to searches are over time. The default embed script tho will not work in your Nuxt.JS app.

If you paste it as-is you will see the error:

Uncaught SyntaxError: expected expression, got '&'

So we should tell Nuxt.JS to run the script only on the client using the <client-only> tag. Now you will see:

Uncaught ReferenceError: trends is not defined

It appears that the second part of the embed code Google provides is trying to run before the first is ready. I'm not sure why this happens inside Nuxt.JS/Vue and not in a normal browser session but we can fix that by moving the initialization code into a function and then calling that function using the onload event on the primary script.

Now you will experience one of two things - either the page will reload with only Google Trends and not your content or you'll get an error about the DOM being changed. This is due to the use of document.write in the default embed code.

Thankfully Google includes a renderExploreWidgetTo function which leads us to...

The solution

Instead of using the default embed code, adapt this version to your needs replacing just the contents of the initTrends function with the part from your Google Trends embed code and viola!

<template>
  <main>
    <div id="trendChart"></div>
    <client-only>
      <script>
        function initTrendChart() {
          trends.embed.renderExploreWidgetTo(
            document.getElementById("trendChart"),
            // Replace this block with yours
            "TIMESERIES",
            {
              comparisonItem: [
                {
                  keyword: "ZX Spectrum",
                  geo: "",
                  time: "2004-01-01 2021-07-01",
                },
              ],
              category: 0,
              property: "",
            },
            {
              exploreQuery: "date=all&amp;q=ZX+Spectrum",
              guestPath: "https://trends.google.com:443/trends/embed/",
            }
          );
        }
      </script>
      <script
        type="text/javascript"
        src="https://ssl.gstatic.com/trends_nrtr/2578_RC01/embed_loader.js"
        onload="initTrendChart()"
      ></script>
    </client-only>
  </main>
</template>

If you need multiple charts you'll need to create multiple divs and paste multiple blocks into initTrendChart to ensure they are all initialized. You do not need multiple copies of the embed_loader script.

This also works just fine with markdown files used to render content via Nuxt Content.

Enjoy!

[)amien

0 responses