Handle external links with Render Hook Templates

Just wanted to share how to handle external links thanks to Render Hook Templates.

Put the following:

<a href="{{ .Destination | safeURL }}"{{ if ne true (in (urls.Parse .Destination).Host (urls.Parse .Site.BaseURL).Host) }} target="_blank"{{ end }}>{{ .Text }}</a>

Inside:

layouts
└── _default
    └── _markup
        └── render-link.html

Notice: from a UX point of view, it is not really recommended to force external links to open in new tabs. You may add an “external link” icon after the link text instead.

I created a PR in case one wants to include this example in the docs.

I think I would go for the simpler:

{{ if strings.HasPrefix .Destination “http” }} target=“_blank”{{ end }}

I guess you mean that with canonifyURLs: false (default) ?

No, I mean exactly what I wrote. Nothing more or less.

Then I don’t understand, because we can have internal links begining with “http”, and ultimately all links begin with “http”.

(Also I noticed I had to reload the Hugo server sometimes for the changes in render-link.html to take effect)

It seems render-link is processed before URLs are canonified, so @bep’s code works perfectly even though I have canonifyURLs set to true. :+1:

But links like [a link](http://mydomain.com/blog) will be treated as external, no? That’s why I chose (urls.Parse .Destination).Host, to be sure to treat links correctly even if the content editor puts a “full” internal URL. Bep’s code assume that all internal links are written without “http” in front of them, right?

Yes. But if this was my blog, I would write every relative URLs in markdown like this:

[a link](/blog/mypost.md)

And every link out to the world like this:

[a link out on the internet](https://example.org/some-external-link)

Note that I have kept the link as a filename (mypost.md); that way I guess the links will also work when browsed on github.com.

I would probably also write variants of the above like this:

[a link](../blog/mypost.md)

And then use .Page.GetPage in the hook template for every non-external link.

If you do this and then use .Permalink for all your linking, there should be no need for canonifyURLs (I think…)

Ok!

I’d rather not depend on conventions for content editors to write URLs.
And I canonify links for mixed content, assets resolving and SEO reasons.