HUGO

How to Open Link in New Tab with Hugo's new Goldmark Markdown Renderer in v0.62.0

In v0.62.0, Hugo has switched to the new Goldmark Markdown Renderer by default, instead of the Blackfriday renderer used previously. Goldmark also introduces a new way to add Markdown Render Hooks to control custom behaviour, e.g. image processing or opening links in new tabs by adding target="_blank" attribute to the links.

I’ve written an article detailing the Goldmark changes as well as how to configure Markdown Render Hooks here: https://agrimprasad.com/post/hugo-goldmark-markdown/

TLDR of the article is that if you just want to be able to open links in new tab for your Hugo site, create a file at layouts/_default/_markup/render-link.html with the following content:

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

Thanks, it was helpful. However, using it in my blog, I have found out it could be improved even more:

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

{{ .Text | safeUrl }} handles a corner case where you render link which is marked as code, e.g. [`hrefTargetBlank`](http://example.com/hugo-docs) doesn't work. Without | safeHTML the link text it is rendered verbatim as <code>hrefTargetBlank</code> instead of being styled as code.

See the related merged PR to the Hugo documentation.

1 Like

I found this really helpful @szpak.

Just to not that your line has a small type-o in it where your second fuction call uses safeUrl not the correct capitalisation (safeURL).

Making the corrected line:

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

Thanks @briggySmalls. In fact there is a difference even in comparison to my linked PR :).

However, as it is a text context and can contain different elements it would be even better to use safeHTML instead of safeURL. Unfortunately, I’m no longer able to edit that post. Therefore, the updated line here, again:

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

And, for security /performance reasons, add rel="noreferrer noopener":

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

@h-enk Sounds reasonable. You might consider propose that change to the Hugo documentation.

1 Like

Hey @szpak, good point. I just did that.

This seems not to work for plain URL links?
I tried the method, but no target="_blank" is added at any href …

Just what I was looking for. Thanks. I tried a few things but could not figure out how to also make this work with mailto links. I duplicated the line and changed http to mailto and that made duplicate links.

I tried a new render-mailto.html file which did nothing. I guess some type of if statement in the render-link.html so it picks up either http or mailto … I know that this is a minor edge case using gmail but inquiring minds and all.

you have to use render-link! Here my implementation:

{{ if strings.HasPrefix .Destination "mailto" -}}Send mail to {{end}}
<a href={{ .Destination | safeURL }}
    {{ if strings.HasPrefix .Destination "http" -}} target=_blank rel="noopener noreferrer" {{- end }}
>{{ .PlainText | htmlEscape }}</a>
1 Like

this worked for me. it opens either mailto or http or https links from markdown files in a new tab. Thanks for your help

<a href={{ .Destination | safeURL }}
    {{ if strings.HasPrefix .Destination "mailto" -}} target=_blank {{end}}
    {{ if strings.HasPrefix .Destination "http" -}} target=_blank rel="noopener noreferrer" {{- end }}
>{{ .PlainText | htmlEscape }}</a>
1 Like