1

I need to add custom HTML containing a template script to a Docusaurus site (built on React), but the site has no .html files - just .js files that are then compiled to create a static site. Specifically, I need to add a .html file that has a <script type="text/template"></script> block, which means I can't just render it with React/JSX like normal HTML elements.

Here is my attempt to do so so far, which is resulting in a literal string being displayed on the page with the contents of my <script type="text/template"></script> block:

Footer.js

const React = require('react');

// for instantsearch
const fs = require('fs'); //Filesystem  
const resultsTemplate = fs.readFileSync(`${process.cwd()}/static/resultsTemplate.html`,"utf-8");

class Footer extends React.Component {
  ...
  render () {
    return (
      <footer className='nav-footer' id='footer'>
        ...

        {resultsTemplate}

      </footer>
    );
  }
}

module.exports = Footer;

If I don't use fs and just set

const resultsTemplate = require(`${process.cwd()}/static/resultsTemplate.html`);

I get the following error upon running npm start:

(function (exports, require, module, __filename, __dirname) { <script type="text/template" id="results-template">
                                                              ^

SyntaxError: Unexpected token <

Which is why I'm using fs.

This is resultsTemplate.html, which I want to inject to the footer:

<script type="text/template" id="results-template">
  <div class="ais-result">
    {{#hierarchy.lvl0}}
    <div class="ais-lvl0">
      {{{_highlightResult.hierarchy.lvl0.value}}}
    </div>
    {{/hierarchy.lvl0}}

    <div class="ais-lvl1">
      {{#hierarchy.lvl1}} 
        {{{_highlightResult.hierarchy.lvl1.value}}} 
            {{/hierarchy.lvl1}} 
        {{#hierarchy.lvl2}} > 
     ...
    </div>
    <div class="ais-content">
        {{{#content}}} 
            {{{_highlightResult.content.value}}} 
        {{{/content}}}
    </div>
  </div>
</script>

Finally, here's the function that's supposed to populate the template with the correct values (taken from Algolia):

  mainSearch.addWidget(
    instantsearch.widgets.hits({
      container: '#search-hits',
      templates: {
        empty: 'No results',
        item: $('#results-template').html()
      },
      hitsPerPage: 10
    })
  );

For more context, I'm trying to implement this functionality in my site: https://jsfiddle.net/965a4w3o/4/

bildungsroman
  • 437
  • 1
  • 8
  • 17

1 Answers1

1

I ended up finding my own solution, thanks in huge part to Giannis Dallas's accepted answer to this question: add raw HTML with <script> inside Gatsby React page

The solution:

Footer.js

const React = require('react');

// for homepage instantsearch
let resultsTemplate = `
<script type="text/template" id="results-template">
  <div class="ais-result">
    {{#hierarchy.lvl0}}
    <div class="ais-lvl0">
      {{{_highlightResult.hierarchy.lvl0.value}}}
    </div>
    {{/hierarchy.lvl0}}

    ...
    </div>
    <div class="ais-content">
      {{{#content}}} {{{_highlightResult.content.value}}} {{{/content}}}
    </div>
  </div>
</script>
`
...

class Footer extends React.Component {
  ...
  render () {
    return (
      <footer className='nav-footer' id='footer'>
        ...

        <div dangerouslySetInnerHTML={{ __html: resultsTemplate }} />

      </footer>
    );
  }
}

module.exports = Footer;

Hope this helps others in a similar situation using React-based static site generators like Docusaurus or Gatsby!

bildungsroman
  • 437
  • 1
  • 8
  • 17