Accessing hugo's template variable inside Javascript files?

I have a javascript file (.js extension) which has a variable to hold a URL.

I want this URL to be different when I build for local server versus when I build for production server.

I am able to do such URL changes for HTML files by placing HTML template files within layout folder and using the template variables such as {{ .Site.BaseURL }}.

But, when I place the .js file within the same layout folder and use the above templating mechanism, hugo doesn’t replace the template variable with the expected value in the output.

Is it possible to use the templating within .js files?

PS: I do not have the option of inlining my javascript into HTML files.

Look into Hugo’s custom output feature.

That worked, Thanks!

Hello @geekybiz, @moorereason

I have a similar problem:

  • Want to use chart.js for creating cheezy charts.
  • data source will be some CSV/json file created by an external program.
  • I can easily take the data file to present them with hugo. No pb.

The problem is that chart.js needs the data inside a javascript file. See example.

So i can’t use my variables/template inside the javascript file to incorporate my data inside the javascript.

I looked at the upper tip custom output, but (dumbly) can’t figure how you solved it :frowning:

Did you generate the javascript file entirely with hugo ??
Do you have an other method ?

Ant tip/link/example would help me greatly. Thanks in advance.

I had the same issue with highchart.js. Instead of using the .js file, I created a .html partial and added the highchart script between the tag.

Where you want your chart to show
<div id="container"></div>

This is how I called the partial:
{{ partial "highcharts.html" . }}

highchart.html partial example

        data: [
            {{ range first 5 $.Site.Taxonomies.apps.ByCount }}
                         name: '{{ replace .Name "-" " " | title }}',
                                y: {{ .Count }},                        
               {{ end }}

@kenold you can “fence” your code blocks on here by putting a line with three backticks before and after.

<script>etc etc</script>

Thanks @RickCogley :slight_smile: I was replying from my phone. I had to edit the post 3 times but still couldn’t fix indentation.

Phones and tablets really don’t make it easy to write code. :slightly_smiling_face:


Unsure how I got it to work with custom output formats but I remember adding the media type application/javascript to my config.toml and then putting my template JS file somewhere within layouts folder. However, due to some reasons - that eventually didn’t work out for me.

Since then, I have been living with a hack where my build shell script has a sed command to change the specific variable to a value in that specific js file. So, I run hugo to get my output files and I run sed command right after hugo to modify this specific variable in the outputted js file. Not the most ideal, but that’s what is getting my task done so far.

Thanks a lot everybody. I got it to work.

Result is here, in case someone would reuse it:

Markdown :

title: "Test charts.js"
{{% chart id="myChart2" width="1600" height="900" csvfile="data/data1.csv" graphtype="radar" %}}

Shortcode : chart.html

<!-- File as parameter -->
{{ if .Get "csvfile" }}
    {{ $csvURL := .Get "csvfile" }}
    {{ $csv := getCSV "," $csvURL }}

    <!-- Count CSV line number (-1 for labels) for generating 1 different color by DATA line -->
    {{ $.Scratch.Set "nbLines" -1 }}        <!-- First line = label not data -->
    {{ range $i, $v1 := $csv }}
        {{ $.Scratch.Add "nbLines" 1 }}     <!-- Count CSV line number -->
    {{ end }}

    <!-- Init the graphic for Chart.js-->
    <canvas id="{{ .Get "id"}}" width="{{ .Get "width" }}" height="{{ .Get "height" }}"></canvas>

        <script> /* INLINE script to work OK with Hugo variables & shortcode */

            /*  Original script from Chart.js */

            var ctx = document.getElementById("{{ .Get "id" }}");
            var myChart = new Chart(ctx, {
                type: 'radar',
                data: {
                    {{ range $i, $v1 := $csv }}     /* loop lines from CSV files */

                        {{ if eq $i 0 }}            /* 1rst line = CSV Header = labels */
                        labels: [
                            {{ range $j, $v2 := . }}
                                {{ if ne $j 0 }}    /* line title (except useless 1rst) */
                                    {{ . }},
                                {{ end }}
                            {{ end }}
                            datasets: [             /* will be filled with the next loop */
                        {{ end }}                   /* end test for 1rst line */

                        {{ if ne $i 0 }}            /* After 1rst line = regular data lines */
                            {                       /* We are in one of the data lines */
                            {{ range $j, $v2 := . }}
                                {{ if eq $j 0 }}    /* label line */
                                    label: {{ . }},
                                    data: [
                                {{ else }}          /* data from $j line */
                                    {{ . }},
                                {{ end }}
                            {{ end }}

                            backgroundColor: [
                                'rgba(255, 209, 132, 0.2)',  /* TODO color index by */
                            borderColor: [
                                'rgba(255, 99, 132, 1)', /* TODO color index by */
                            borderWidth: 1.4
                            },                  /* end of 1 dataset = 1 line */
                        {{ end }}               /* end test for regular line */

                    {{ end }}                   /* end loop CSV file */
                    ]                           /* close the datasets label */

                options: {
                    scale: {
                        display: true
            })                                  /* End function for Chart.js */


    <!-- Call the Chart routine -->
    <script src="../../js/Chart.min.js"></script>
    <!-- Online source : "" -->


{{ end }}

CSV sample

"Titre","Primes récurrentes","Assurance vie","Assurances Décennale","Assurances Habitation Professionnelle","Automobile","Bris de Machines","Complémentaire Santé","Construction DO PUC CNR TRC","Divers","Dommages aux Biens","Individuelle Accident","Maritime et Transport","Multirisque Habitation Particulier","Multirisque Immeuble","Multirisque Professionnelle","Navigation de Plaisance","Perte d'Exploitation","Protection Juridique","Prévoyance","RISQUES SPECIAUX","RISQUES TECHNIQUES","Responsabilité Civile"
"Situation N-1",1717.61,3450.00,6617.91,1659.82,7164.69,4560.00,450.00,5218.54,7770.00,3297.31,4420.00,2240.00,4896.33,4340.00,1420.54,4340.00,4340.00,430.00,430.00,430.00,4440.00,1442.47
"TEST ligne 2 CSV",2240.00,4896.33,4340.00,1420.54,4340.00,4340.00,430.00,430.00,430.00,4440.00,1442.47,1717.61,3450.00,6617.91,1659.82,7164.69,4560.00,450.00,5218.54,7770.00,3297.31,4420.00
"TEST ligne 3 CSV",430.00,430.00,430.00,4440.00,1442.47,1717.61,3450.00,6617.91,2240.00,4896.33,4340.00,1420.54,4340.00,4340.00,1659.82,7164.69,4560.00,450.00,5218.54,7770.00,3297.31,4420.00
"TEST ligne 4 CSV",2240.00,4896.33,4340.00,1420.54,4340.00,1717.61,3450.00,6617.91,1659.82,7164.69,4560.00,450.00,4340.00,430.00,430.00,430.00,4440.00,1442.47,5218.54,7770.00,3297.31,4420.00

Only problem left is color is hard coded (one by data in this ‘radar’ case, but same with a full list of color for “line” type for example.

I didn’t found how to generate a color palette in hugo, so I looked for some cool javascript librairies ( for a simple example).

Problem is I can’t reuse it in this script because it is writing the javascript code loop and not execute it.

So I guess I have to find an other solution.
Any tip/idea for not having my colors harcoded ?