Hugo Opening External Links in new Tab

Introduction

In my Hugo website, the external links were opening by default in the same browser than my current page, and often I was forcing myself to hold CTRL key when clicking on those links. It was doing the trick until it became a bad habit … I was starting to hold CTRL key when clicking on anylink ! At that point it was time to find a way to make this work automatically.

Html trick

The trick to force a link to open a link in another tab or browser is to use target="_blank" rel="noopener noreferrer" in the anchor.

As I am using Markdown for my posts, I need a way to enforce those code in my URL. Fortunately, Hugo has an impressive feature : Render Hooks . There is a piece of code to customize links :

1
<a href="{{ .Destination | safeURL }}"{{ with .Title }} title="{{ . }}"{{ end }}{{ if strings.HasPrefix .Destination "http" }} target="_blank" rel="noopener"{{ end }}>{{ .Text | safeHTML }}</a>

I have created a file render-link.html in folder layouts/_default/_markup/ with this line of code. It is possible to make it prettier and more easy to read. In debug mode the html source code will show multiple line, but when deploying in production, the --minify option will optimize the source and remove all unnecessary white spaces.

Readable script :

1
2
3
4
5
<a href="{{ .Destination | safeURL }}" 
    {{ with .Title}} title="{{ . }}" {{ end }} 
    {{ if strings.HasPrefix .Destination "http" }} target="_blank" rel="noopener noreferrer" {{ end }}>
    {{ .Text | safeHTML }}
</a>

Html source in Debug mode :

1
2
3
4
5
<a href="https://gohugo.io/templates/render-hooks/" 
     
     target="_blank" rel="noopener noreferrer" >
    Render Hooks
</a>

Html source in Production mode :

1
<a href=https://gohugo.io/templates/render-hooks target=_blank rel="noopener"/>Render Hooks</a>

Notice the double-quotes have disappeared around the target and the href attribute.

To apply the same principle to external links from menus, I had to look for the partial dealing with the menu rendering. I added the check for the http prefix in the url as follow :

1
2
3
4
5
6
7
    ...
        {{ range .Site.Menus.nav }}
        <li class="nav-item">
          <a class="nav-link active" aria-current="page" href="{{ .URL }}"{{ if strings.HasPrefix .URL "http" }} target="_blank" rel="noopener noreferrer" {{ end }}>{{ .Name }}</a>
        </li>
        {{ end }}
    ...

Conclusion

Just by adding this small script all external links are now opening in external tab.

I ❤️ Hugo !

References