Here’s something I have achieved today: I got my site to display an “external link” SVG icon at the end of all links generated from Markdown, using Hugo’s neat markdown render hooks(external link). Basically, when Hugo is translating Markdown source files into an HTML built site, it turns Markdown links into HTML ones following a certain template – but by creating your own template at a specific location, you can tell it to translate them your way instead! So, I created a new file at /layouts/_default/_markup/render-link.html that goes:

<a href="{{ .Destination | safeURL }}"{{ with .Title}} title="{{ . }}"{{ end }}>{{ .Text | safeHTML }}{{ if strings.HasPrefix .Destination "http" }}<span style="white-space: nowrap;">&thinsp;<svg style="height: 0.7em; width: 0.7em;" focusable="false" data-prefix="fas" data-icon="external-link-alt" class="svg-inline--fa fa-external-link-alt fa-w-16" role="img" xmlns="" viewBox="0 0 512 512"><title>external link</title><path fill="currentColor" d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"></path></svg></span>{{ end }}</a>

What this does is, if the link destination begins with “http”, it appends this SVG from Font­Awe­some(external link). I used the same technique I described here to embed the SVG directly in my code instead of through an <img> tag, so it can take on the colour of the rest of the link automatically. This also works only because I make sure to always use relative links to link to other pages on my own site – if I used absolute links, those would appear with the “external link” icon too. If I really want to link to an external page without the icon appearing, I can use the HTML <a href="">...</a> instead.1 That’ll bypass Hugo’s markdown handling, so no icon will be added 🙂

Also note, I have adapted FontAwesome’s SVG code for my intended purpose… mainly I have:

  • added style="height: 0.7em; width: 0.7em; (so it appears at a suitable size inline)
  • added <title>external link</title>, as per CSS Tricks’ Accessible SVGs guide(external link) (title + desc tags are like the SVG equivalent of alt text apparently)
  • removed the aria-hidden="true" attribute, which tells browsers the element is purely decorative and neither has nor needs alt text (…because I added some).

I note this because under the terms of Font­Awe­some’s CC BY 4.0 Licence(external link) I am required to indicate any changes I have made to their work. I’m not sure whether that was intended to include tinkering with the metadata of the SVG but I wanted to err on the side of caution.

Important Note: If you just grab my code snippet above, you will also be bound to their CC BY 4.0 Licence! Click through so you know what you’re agreeing to, and make sure to provide credit to them for their free icon 👍 Outside of this post I stuck mine in the “site” section of my about page, which I think is an “appropriate” and “reasonable” place (as per the licence terms) to put it.

If you don’t want to use their icon, then of course, you can replace the entire <svg> tag in my snippet with whatever you like (and will not be bound to their licence). Your own icon, perhaps. Maybe one of Wikimedia’s “external link” icons(external link) (check the individual licences but some are GPL, some are CC, and some are public domain). Or you could replace it with a Unicode arrow, like ↗, or a text string like “[ext]”. The power is yours!

Another styling thing that I would note: I wanted to make sure the icon would always appear on the same line as the last word of the link, which turned out to be way harder than you might think it would’ve been. &nbsp; didn’t work and in any case was way too wide, especially in Firefox where it was displaying as an em-space. My solution was to add <span style="white-space: nowrap;">&thinsp; just before the SVG and </span> just after it. (Trying to end the span immediately after &thinsp; meant the line would still wrap there in Safari.) &thinsp; itself is a space that’s 0.2em wide, so there’s only a nice slender gap between my link text and the icon.

As for why any of this might be useful, mainly it’s for my personal wiki pages, to make it easier for people to tell when they’re clicking a link to elsewhere within my wiki as opposed to somewhere off-site. There might be some blog posts where making the distinction explicit could be helpful too, I don’t know. The point is: it seemed a potentially useful indicator 🙂

  1. I can do this because I have my Hugo config set to allow “unsafe” markup in posts(external link) (which, contrary to the alarmist name, just means you can use HTML directly in your Markdown-formatted posts, which is explicitly allowed in Markdown specs like CommonMark(external link) anyway…) ↩︎