2

I'm trying to add the wowhead tooltips to a docusaurus page.

The wowhead documentation suggests you need to add the following to your <head> section:

<script>const whTooltips = {colorLinks: true, iconizeLinks: true, renameLinks: true};</script>
<script src="https://wow.zamimg.com/widgets/power.js"></script>

I can add the https://wow.zamimg.com/widgets/power.js fine using the scripts configuration option which works fine with defer or async:

module.exports = {
  // Snipped rest of configuration
  scripts: [
    {
      src:
        'https://wow.zamimg.com/widgets/power.js',
      defer: true,
    },
  ],

For the inline portion <script>const whTooltips = {colorLinks: true, iconizeLinks: true, renameLinks: true};</script> I have tried using a <Head> component in my index.js <Layout> section and had no success.

How can I add this inline script properly to docusaurus so it loads before the wowhead script?

Alex.Ritna
  • 1,957
  • 2
  • 16
  • 24
  • 1
    Try this https://docusaurus.io/docs/lifecycle-apis, I think you need to use the function `injectHtmlTags`. – D.Kastier Aug 11 '21 at 17:53
  • using `injectHtmlTags` I am able to inject the two scripts and they load successfully, however now I am having trouble with the library loading the options and it seems to be related to the dynamic content. Running this from the console "updates" everything correctly: `window.$WowheadPower.refreshLinks();`. Any way I can run this after the page has rendered? I can't see a way to do a useEffect() style call with docusaurus. – Alex.Ritna Aug 11 '21 at 20:08

2 Answers2

1

Using the advice from D.Kastier, I successfully solved my problem, granted it wasn't very elegant.

To load the script properly, and have it update after the page initially loads:

     injectHtmlTags() {
       return {
         headTags: [
           // https://www.wowhead.com/tooltips
           {
             tagName: 'script',
             innerHTML: `
               const whTooltips = {colorLinks: true, iconizeLinks: true, renameLinks: true};

               document.addEventListener('readystatechange', event => {
                 if (event.target.readyState === "complete") {
                   console.log('Updating tooltips from plugin');
                   window.$WowheadPower.refreshLinks();
                 }
                });
             `,
           },
           {
             tagName: 'script',
             attributes: {
               defer: true,
               src: 'https://wow.zamimg.com/widgets/power.js',
             },
           },
         ],
       };
     },

Then to update the tooltips each time the page changes:

    onRouteUpdate({location}) {
      setTimeout(function() {           
          window.$WowheadPower.refreshLinks(); 
        }, 0);
    },
Alex.Ritna
  • 1,957
  • 2
  • 16
  • 24
  • As an aside, I will post another question regarding the best way to run the `window.$WowheadPower.refreshLinks()` after components have loaded & rendered in the docusaurus ecosystem, as that's far outside my docusaurus/react expertise. – Alex.Ritna Aug 12 '21 at 04:40
  • 1
    I am happy that I could help! Now I have another hunch: instead of putting the script in the `headTags` try put then in the `postBodyTags`. This will load the script only after the body was created — it may or may not work… – D.Kastier Aug 12 '21 at 11:17
  • And/or you could put the script `window.$WowheadPower.refreshLinks();` in the `postBodyTags` – D.Kastier Aug 12 '21 at 11:18
  • This doesn't resolve the issue either, looks like because this runs before docusaurus properly loads the page content, it doesn't get chance to update the DOM. I'd need a way to run that snippet **after** docusaurus loads the content into `
    `
    – Alex.Ritna Aug 12 '21 at 15:58
  • 1
    Try adding an event listener on the DOM: `document.addEventListener('readystatechange', event => {if (event.target.readyState === "complete") window.$WowheadPower.refreshLinks();});` – D.Kastier Aug 12 '21 at 16:11
  • 1
    I can't find any documentation... But I think you will need to use the `onRouteUpdate` to run the script... [See this](https://blogs.thebitx.com/index.php/2021/06/17/update-react-component-state-on-every-route-change-in-docusaurus-by-amrish-kushwaha-jun-2021/) for some light – D.Kastier Aug 12 '21 at 16:21
  • 1
    Using `onRouteUpdate` works for pages that are navigated to, but only if I wrap the `window.$WowheadPower.refreshLinks();` call in a `setTimeout()` with a 1ms timeout. I added the event listener to the DOM as you suggested and this only runs the first time a page is rendered. Between the two, while I don't fully understand why it's working, it does seem to be working. – Alex.Ritna Aug 12 '21 at 16:33
  • Updated my answer with the solution that loads the script, configures it, refreshes it on page load & subsequent route changes. Thanks for your help @D.Kastier ! – Alex.Ritna Aug 12 '21 at 16:58
  • Nicely done! I happy for you, and you are welcome! – D.Kastier Aug 12 '21 at 18:15
0

We can head tag directly in docusourus.cofig.js

  headTags: [
    {
      tagName: 'script',
      attributes: {
        type: 'text/javascript',
      },
      innerHTML: `
      console.log('I am JavaScript')
      `
    }
  ],
Abhay
  • 3,151
  • 1
  • 19
  • 29