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/

1 Answer 1

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!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.