Gnimuc
Gnimuc

Reputation: 8576

how to access Hugo's template variables in a javascript file?

I'm trying to use react.js in Hugo. I know Go template variables are accessible in HTML file.

My question is how to access them in javascript. or is there a workaround?

thanks in advance.

UPDATE:

currently my workaround is to use meta tags in HTML and load Go template variables like this:

<meta name="title" content={{.Title}} />

and then in javascript,

function getMetaTitle() {
   var metas = document.getElementsByTagName('meta');

   for (i=0; i<metas.length; i++) {
      if (metas[i].getAttribute("name") == "title") {
         return metas[i].getAttribute("content");
      }
   }

   return "failed to access...";
}
var metaTitle = getMetaTitle();

but this way is inconvenient when the number of meta tags growing, is there a more concise way to do this?

Upvotes: 6

Views: 5400

Answers (3)

Punit S
Punit S

Reputation: 3247

You can specify a custom output format for Javascript within your config.toml so that Hugo then treats those particular formats and file extensions like it's content files where it replaces the template variables with adequate values.

So, an entry such as below in your config.toml will treat javascript files as one of the media type it needs to consider for its custom output formats:

[mediaTypes]
    [mediaTypes."application/javascript"]
    suffix = "js"

You can read more about it here

Upvotes: 2

revelt
revelt

Reputation: 2420

I doubt Hugo and React is a good pair but that's off topic and I might be wrong about that. You are asking, how to get Hugo variables into website's JavaScript. My answer:


Hugo is static website engine, so it only converts templates and markup documents (with your content) into HTML files. Now, when you upload your files onto your server, your JS cannot see anything Hugo — only your files.

The question becomes, how to transfer Hugo variables into some files of your website.

As you suggested, it's best to write variables into your HTML (or JSON) using Hugo, then read them by JS. If it's small amount, use attributes or tags. If there's a lot and it doesn't differ per-page, use a separate JSON file.

For example, personally I have a multilingual site which a) requires different language titles to appear dynamically via JS; b) uses JS which queries different Lunr.js search indexes in JSON format.

For both I use data-<name> attributes:

    <section class="section-search" data-index="{{ .Site.BaseURL }}searchIndex.json" id="section-search">
      <input type="search" id="search-input" placeholder="{{ ( index $.Site.Data.translations $.Site.Params.locale ).dataloading }}" data-loaded="{{ ( index $.Site.Data.translations $.Site.Params.locale ).dataloaded }}">
      <!-- search button goes here -->
    </section>

For example, on English templates (rendered into /public/), data-loaded attribute would be in English, but for Lithuanian templates (rendered into /public/lt/), data-loaded attribute would be in Lithuanian.

I wouldn't worry about "growing meta tags", but you could maybe write variables into a JSON file and then read it in JS if you are concerned about HTML bloat?

I'm building custom JSON first as HTML, then minifying/renaming it into JSON when building indexes for Hugo Lunr search as per this recipe. Instead of "baking in" the content with range as in mentioned recipe, you could simply list all the variables.

By the way, I'm using npm scripts as a build runner (instead of Grunt/Gulp) so I use json-minify:

"index:prepare": "json-minify public/json/index.html > public/site-index.json",

You could "bake" JSON files with any content (including Hugo template variables) via Hugo this way. Hope it helps.

Upvotes: 5

bep
bep

Reputation: 1737

You can, of course, inline your JS in your layout files, but that is probably not what you want.

There have been some discussions about improvements in this area on the Hugo discussion site, but nothing concrete yet.

Upvotes: 0

Related Questions