Add external javascript, like Google Analytics or Ad Servers

Hello! If I need to use a custom javascript file (executed on client side) what would be the correct way?

2 Likes

What’s the use case?

For example to check after a seconds if the ads are correctly loaded.

Or for example add external javascripts like analytics or google tag manager, smartadserver, etc.

Can’t you use the afterCSR action (after-client-side-rendering) to do that?

export default {
   ...
   actions: {
      theme: {
         afterCSR: ({ state }) => {
           setTimeout(() => {
              // check something
           }, 1000);
         },
      }
   }
}

I think those can be added as React components, can’t they?

const SmartAdsHeader = ({ state }) => (
  <Head>
    <script
      src={`//ced.sascdn.com/tag/${state.theme.smartAds.networkId}/smart.js`}
      type="text/javascript"
      async
    />
  </Head>
);

Finally, if you need React components to execute something after mount, you can do it with useEffect:

const SmartAd = ({ tagId, width, height, callType, callParams }) => {
  
  // Run this for each SmartAd component, on mount.
  useEffect(() => {
     const sas = window && window.sas ? window.sas : (window.sas = {});
     sas.cmd = sas.cmd || [];
     sas.cmd.push(() => {
       const containerExists = window.document.getElementById(callParams.tagId) !== null;
       if (containerExists) {
          sas.call(callType, { async: true, ...callParams });
        }
     });
  }, []);

  return (
    <div
      className="sas-ad"
      id={tagId}
      width={width}
      height={height}
    />
  );
};

Let me know if that helps.

1 Like

This is perfect! I did the

export default {
 ...
actions: {
   theme: {
     afterCSR: ({ state }) => {
       setTimeout(() => {
          // check something
          console.log("Hello world!");
       }, 1000);
     },
  }
}

And if works perfect, but It only works one time (when the first page is loaded) if I click on one post this is not executing again (which is normal). But what would be the best way to set a trigger when the route link changes?

Thanks for the help!

Oh, I see. You need to observe to either actions.router.set or state.router.link.

We are going to add middleware to the state manager (@frontity/connect) to be able to do both of those things. It’s up in the roadmap, coming in the next 2-3 months :slight_smile:


Until then, you can use observe, like this:

import { observe } from "frontity";

afterCSR: ({ state }) => {
  observe(() => {
    console.log(state.router.link);
  })
}

That function should run each time state.router.link changes.