How to open plain URL links in a new tab?

Using new Hugo 0.6x on Windows, I try to open plain URLs in a new tab.
All hints I found, discuss other forms of links and don’t work -
no target="_blank" is added to the href lines.

What do you mean with a plain URL /could you provide an example of what you’re trying to achieve?

The form of link as described in the Markdown Guide https://www.markdownguide.org/basic-syntax/#links

URLs and Email Addresses

To quickly turn a URL or email address into a link, enclose it in angle brackets.

<https://www.markdownguide.org>
<fake@example.com>

I need them in a FAQ-like website with many links -
so some editing would not help.

And if you look at this (somewhat similar) question - there is also noch answer until now:

Assuming you have a layouts\_default\_markup\render-link.html (REF: https://gohugo.io/getting-started/configuration-markup/#render-hook-templates) with something like:

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

Then, these formats do (indeed) NOT open in a new tab:

<https://www.markdownguide.org>
<fake@example.com>

However, this link format DOES open in a new tab:

[https://www.markdownguide.org](https://www.markdownguide.org)

Hope this helps.

3 Likes

TLDR: I’ve listed possible workarounds at the end of this post.

Assuming that you have not set linkify = false under [markup.goldmark.extensions] in your site’s config.toml file, the following markdown:

www.example.com  
<https://www.example.com>  
[https://www.example.com](https://www.example.com)  
[https://www.example.com][1]

[1]: https://www.example.com

produces this HTML:

<a href="http://www.example.com">www.example.com</a>
<a href="https://www.example.com">https://www.example.com</a>
<a href="https://www.example.com">https://www.example.com</a>
<a href="https://www.example.com">https://www.example.com</a>

Similarly, with email addresses, this markdown:

fake@example.com  
<fake@example.com>  
[fake@example.com](mailto:fake@example.com)  
[fake@example.com][2]

[2]: mailto:fake@example.com

produces this HTML:

<a href="mailto:fake@example.com">fake@example.com</a>
<a href="mailto:fake@example.com">fake@example.com</a>
<a href="mailto:fake@example.com">fake@example.com</a>
<a href="mailto:fake@example.com">fake@example.com</a>

In the markdown for each example, the first two link formats contain a destination only. The last two contain both text and destination. The markdown render hook is not fired for the link formats without text.

Recommendation

Create an issue on GitHub. I’m not sure if this is a bug or an enhancement.

Workarounds

1) Manually edit your markdown to use the [xxx](xxx) format. This is the safest of the workarounds that I have described.

2) Use a tool such as sed to perform a search/replace en masse, making sure that you backup all of your content files before proceeding. For example:

sed -E -i 's/<(https?:\/\/.*)>/[\1](\1)/' test.md
sed -E -i 's/<(.*@.*)>/[\1](mailto:\1)/' test.md

The above commands will convert this:

<https://www.example.com>
<http://www.example.com>
<fake@example.com>

to this:

[https://www.example.com](https://www.example.com)
[http://www.example.com](http://www.example.com)
[fake@example.com](mailto:fake@example.com)

3) In your single.html file(s), replace {{ .Content }} with:

{{ $content := .Content }}
{{ $content = replaceRE `<a href="(https?://.+)">` `<a href="$1" target="_blank">` $content | safeHTML }}
{{ $content = replaceRE `<a href="(mailto:.+)">` `<a href="$1" target="_blank">` $content | safeHTML }}
{{ $content | safeHTML }}

This will add a duplicate target="_blank" attribute to links that already have a target="_blank" attribute (golang doesn’t support negative lookaheads), but that won’t break anything. I have no idea what performance impact this will have when building a large site. It works, but I don’t like it very much.

2 Likes

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.