<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Leigh Garland</title>
    <description>The latest articles on DEV Community by Leigh Garland (@toychicken).</description>
    <link>https://dev.to/toychicken</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F202032%2Fdc75f675-734f-4c7c-904a-8807d7538ab5.jpeg</url>
      <title>DEV Community: Leigh Garland</title>
      <link>https://dev.to/toychicken</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/toychicken"/>
    <language>en</language>
    <item>
      <title>Using Hugo Render hooks to make links bend to your will</title>
      <dc:creator>Leigh Garland</dc:creator>
      <pubDate>Mon, 07 Oct 2024 09:11:57 +0000</pubDate>
      <link>https://dev.to/toychicken/using-hugo-render-hooks-to-make-links-bend-to-your-will-4j1e</link>
      <guid>https://dev.to/toychicken/using-hugo-render-hooks-to-make-links-bend-to-your-will-4j1e</guid>
      <description>&lt;p&gt;This all began with a post on my socials... &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg3euhtaaf2vvrmxvyyua.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg3euhtaaf2vvrmxvyyua.png" title="Original post" alt="https://mastodon.neilzone.co.uk/@neil/113244632967157645"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mastodon.neilzone.co.uk/@neil/113244632967157645" rel="noopener noreferrer"&gt;https://mastodon.neilzone.co.uk/@neil/113244632967157645&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The consensus certainly seemed to be that it's not possible to do this solely with CSS (which is a shame), but Neil did mention that they were investigating using Hugo to solve this.&lt;/p&gt;

&lt;p&gt;My advice was to use Render Hooks, but I couldn't stop thinking about how  &lt;em&gt;I&lt;/em&gt; might do this, as it seemed like a neat way to present those long external links...&lt;/p&gt;

&lt;h2&gt;
  
  
  This is where I started
&lt;/h2&gt;

&lt;p&gt;You can jump straight to the solution  if you want. Otherwise, read on.&lt;/p&gt;

&lt;p&gt;I spun up a standard Hugo quickstart project, and added some links to my site index page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Here is a variety of links to test Hugo and/or CSS to show just the domain for external links...

&lt;span class="gs"&gt;**Internal links**&lt;/span&gt;
&lt;span class="p"&gt;
*&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Custom text&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;/i_love_cats&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Custom text, with title&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;/i_love_cats&lt;/span&gt; &lt;span class="nn"&gt;"I love cats"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Custom text, absolute path&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;http://localhost:1313/i_love_cats&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="gs"&gt;**External links**&lt;/span&gt;
&lt;span class="p"&gt;
*&lt;/span&gt; Top-level domain, auto-generated text https://cats.org
&lt;span class="p"&gt;*&lt;/span&gt; Deep link, auto-generated text https://www.cats.org.uk/help-and-advice/lost-found-and-feral-cats/lost-found-and-feral-cats
&lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Custom text, Top-level domain&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://cats.org&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Custom text, Top-level domain, with title &lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://cats.org&lt;/span&gt; &lt;span class="nn"&gt;"I love rescue cats"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Custom text, deep link&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://www.cats.org.uk/help-and-advice/lost-found-and-feral-cats/lost-found-and-feral-cats&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Custom text, deep link, with title&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://www.cats.org.uk/help-and-advice/lost-found-and-feral-cats/lost-found-and-feral-cats&lt;/span&gt; &lt;span class="nn"&gt;"Lost &amp;amp; found cats"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I wanted to account for all the ways you can present links in markdown, in Hugo. It looks something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0le3mjvlaoilua7vzvgd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0le3mjvlaoilua7vzvgd.png" title="Unchanged render" alt="Links rendered without adaptation"&gt;&lt;/a&gt;&lt;br&gt;
I think it's those pesky auto-generated deeplinks that Neil wants to make a little prettier.&lt;/p&gt;

&lt;p&gt;The rendered link looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://www.cats.org.uk/help-and-advice/lost-found-and-feral-cats/lost-found-and-feral-cats"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    https://www.cats.org.uk/help-and-advice/lost-found-and-feral-cats/lost-found-and-feral-cats
    &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which doesn't give you much to hook into with CSS.&lt;/p&gt;

&lt;p&gt;This is where Hugo's render hooks come in. For a certain selection of commonly used html elements, Hugo gives you the chance to override the default rendering, and define how you want it to render yourself using the Hugo template system. Hugo provides you with 3 variables for a link.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Post 1&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;/posts/post-1&lt;/span&gt; &lt;span class="nn"&gt;"My first post"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt; ------  -------------  ------------- &lt;/span&gt;
  text    destination      title
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My first step was to add a &lt;code&gt;data-domain&lt;/code&gt; attribute to see if I could use it to replace the content. I created a &lt;code&gt;render-link.html&lt;/code&gt; file in&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;layouts/
    _default/
        _markup/
            render-link.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This now overrides the default markdown rendering for links. I started with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;{{ $u := urls.Parse .Destination }}

&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"{{ .Destination | safeURL }}"&lt;/span&gt; 
&lt;span class="na"&gt;data-domain=&lt;/span&gt;&lt;span class="s"&gt;"{{ $u.Hostname }}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ .Text | safeHTML }}
&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It uses Hugo's &lt;a href="https://gohugo.io/functions/urls/parse/" rel="noopener noreferrer"&gt;urls.Parse&lt;/a&gt; function to take the destination and convert to an object of the various parts of a url. In our case, we just need the &lt;code&gt;Hostname&lt;/code&gt; . I added it to the &lt;code&gt;data-domain&lt;/code&gt; attribute, and our deep link now looks like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://www.cats.org.uk/help-and-advice/lost-found-and-feral-cats/lost-found-and-feral-cats"&lt;/span&gt; &lt;span class="na"&gt;data-domain=&lt;/span&gt;&lt;span class="s"&gt;"www.cats.org.uk"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;https://www.cats.org.uk/help-and-advice/lost-found-and-feral-cats/lost-found-and-feral-cats&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I added a bit to the CSS for links, to show the data-domain attribute as extended content for the link, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;data-domain&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="nd"&gt;::after&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;' - '&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data-domain&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But, this was a bit messy, as the &lt;code&gt;data-domain&lt;/code&gt; was missing for relative links, and rendered some odd dashes at the end of lines. Also, where the markdown had infered the link test from the url, it looked even messier. I couldn't find a neat way to reliably style out the &lt;em&gt;actual&lt;/em&gt; link text leaving only the shorter hostname.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fogb4a0nivq7dpz5ynlv0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fogb4a0nivq7dpz5ynlv0.png" alt="Another screengrab of the output link list,"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Given I had the &lt;code&gt;urls.Parse&lt;/code&gt; method, I now realised I could do something a little more fancy-schmancy, and build up some additional elements, easily styled by CSS. Something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;{{ $u := urls.Parse .Destination }}
&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"{{ .Destination | safeURL }}"&lt;/span&gt;
&lt;span class="na"&gt;data-domain=&lt;/span&gt;&lt;span class="s"&gt;"{{ $u.Hostname }}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"link-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ .Text | safeHTML }}&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"hostname-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ $u.Hostname }}&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which didn't really change the output, but now I had some CSS selectors to work with.&lt;/p&gt;

&lt;p&gt;I created this monstrosity (you would swap out &lt;code&gt;localhost&lt;/code&gt; for your site's domain)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;href&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="nd"&gt;:not&lt;/span&gt;&lt;span class="o"&gt;([&lt;/span&gt;&lt;span class="nt"&gt;href&lt;/span&gt;&lt;span class="o"&gt;*=&lt;/span&gt;&lt;span class="s1"&gt;"://localhost"&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt; &lt;span class="nc"&gt;.link-text&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thinking this would pretty much do the trick, but... it fails on relative links,  because they too don't match the &lt;code&gt;://localhost&lt;/code&gt; domain. Looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6kzjvrcojjv46g8yeuqd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6kzjvrcojjv46g8yeuqd.png" alt="Screenshot, internal links don't show their text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Oops 😦&lt;/p&gt;

&lt;p&gt;I needed to provide a few more class names for the CSS to be able to hook into.&lt;/p&gt;

&lt;p&gt;First up - is this a relative link? For this I need to check if the hostname is empty.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;{{ if not (strings.ContainsNonSpace $u.Hostname )}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basically this checks if the hostname is empty using the &lt;a href="https://gohugo.io/functions/strings/containsnonspace/" rel="noopener noreferrer"&gt;strings.ContainsNonSpace&lt;/a&gt; functionality.&lt;/p&gt;

&lt;p&gt;So I added a &lt;code&gt;$class&lt;/code&gt; variable to store some output, and our template looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;{{ $u := urls.Parse .Destination }}
{{ $class := "" }}

{{ if not (strings.ContainsNonSpace $u.Hostname)}}
    {{ $class = "relative" }}
{{ end }}

&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"{{ .Destination | safeURL }}"&lt;/span&gt; 
&lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"{{ $class }}"&lt;/span&gt;
&lt;span class="na"&gt;data-domain=&lt;/span&gt;&lt;span class="s"&gt;"{{ $u.Hostname }}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"link-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ .Text | safeHTML }}&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"hostname-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ $u.Hostname }}&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the monster css selector looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;href&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="nd"&gt;:not&lt;/span&gt;&lt;span class="o"&gt;([&lt;/span&gt;&lt;span class="nt"&gt;href&lt;/span&gt;&lt;span class="o"&gt;*=&lt;/span&gt;&lt;span class="s1"&gt;"://localhost"&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;&lt;span class="nd"&gt;:not&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;.relative&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;.link-text&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this renders like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F21qpg6us19q4gjqwhdzg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F21qpg6us19q4gjqwhdzg.png" alt="Screenshot, looking better, but still some missing text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Which is looking &lt;em&gt;loads&lt;/em&gt; better, but has nixed the explicit text on the last four of those links 😢 &lt;em&gt;and&lt;/em&gt;  is still showing the domain for the absolute link too.&lt;/p&gt;

&lt;p&gt;I tried a few variations with the CSS, but this is the best it got. &lt;/p&gt;

&lt;p&gt;I needed to make sure I could also explicitly detect an external link AND / OR one with explicit text.&lt;/p&gt;

&lt;p&gt;For this, I needed some more template magic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;{{ $u := urls.Parse .Destination }}
{{ $yourDomain := "localhost" }}
{{ $class := "" }}

{{ if not (strings.ContainsNonSpace $u.Hostname)}}
    {{ $class = "relative" }}
{{ else }}
    {{ if not (compare.Eq $u.Hostname $yourDomain) }}
        {{ $class = "external" }}
        {{ if (compare.Eq $u.String .Text) }}
            {{ $class = "external implied"}}
        {{ end }}
    {{ end }}
{{ end }}

&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"{{ .Destination | safeURL }}"&lt;/span&gt; 
&lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"{{ $class }}"&lt;/span&gt; 
&lt;span class="na"&gt;data-domain=&lt;/span&gt;&lt;span class="s"&gt;"{{ $u.Hostname }}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"link-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ .Text | safeHTML }}&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"hostname-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ $u.Hostname }}&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have a way, by comparing the &lt;code&gt;$u.Hostname&lt;/code&gt; to a &lt;code&gt;$yourDomain&lt;/code&gt; variable, to see if it explicitly external&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{{ if not (compare.Eq $u.Hostname $yourDomain) }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AND we subsequently check to see if the url is the same as the &lt;code&gt;.Text&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;{{ if (compare.Eq $u.String .Text) }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And change the class appropriately. Now we're getting closer! Our rendered deeplink looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://www.cats.org.uk/help-and-advice/lost-found-and-feral-cats/lost-found-and-feral-cats"&lt;/span&gt; 
   &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"external implied"&lt;/span&gt; 
   &lt;span class="na"&gt;data-domain=&lt;/span&gt;&lt;span class="s"&gt;"www.cats.org.uk"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"link-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;https://www.cats.org.uk/help-and-advice/lost-found-and-feral-cats/lost-found-and-feral-cats&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"hostname-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;www.cats.org.uk&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can update our CSS now, to be a little more readable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="nc"&gt;.relative&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;.hostname-text&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="nc"&gt;.external&lt;/span&gt;&lt;span class="nd"&gt;:not&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;.implied&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;.hostname-text&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;none&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="nc"&gt;.external.implied&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;.link-text&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this renders like this. Pretty much nails it... &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp8n2pl7df31nyq4vmem3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp8n2pl7df31nyq4vmem3.png" alt="Screenshot, all text restored, but is showing the link on the absolute internal link"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Bingo!
&lt;/h2&gt;

&lt;p&gt;Grr, then I noticed the absolute link is not accounted for. A simple default on the &lt;code&gt;$class&lt;/code&gt; variable, and an additional definition in the CSS, and it's fixed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;{{ $u := urls.Parse .Destination }}
{{ $yourDomain := "localhost" }}
{{ $class := "internal" }}

{{ if not (strings.ContainsNonSpace $u.Hostname)}}
    {{ $class = "relative" }}
{{ else }}
    {{ if not (compare.Eq $u.Hostname $yourDomain) }}
        {{ $class = "external" }}
        {{ if (compare.Eq $u.String .Text) }}
            {{ $class = "external implied"}}
        {{ end }}
    {{ end }}
{{ end }}

&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"{{ .Destination | safeURL }}"&lt;/span&gt; 
&lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"{{ $class }}"&lt;/span&gt; 
&lt;span class="na"&gt;data-domain=&lt;/span&gt;&lt;span class="s"&gt;"{{ $u.Hostname }}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"link-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ .Text | safeHTML }}&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"hostname-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ $u.Hostname }}&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the CSS...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="nc"&gt;.internal&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="nc"&gt;.relative&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;.hostname-text&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="nc"&gt;.external&lt;/span&gt;&lt;span class="nd"&gt;:not&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;.implied&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;.hostname-text&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;none&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="nc"&gt;.external.implied&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;.link-text&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...and bingo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/hugo-bending-links-bingo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/hugo-bending-links-bingo.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Over-engineering
&lt;/h2&gt;

&lt;p&gt;Yep, that's it. I think this meets the needs of what we wanted in the first place. Namely that it only shows the top-level domain for those implied-text, deeplink urls, and everything else looks as expected...&lt;/p&gt;

&lt;p&gt;But there's a little more...&lt;/p&gt;

&lt;p&gt;Don't forget, Hugo allows us to pass in a 'title' into our markdown, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Custom text, deep link, with title&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://www.cats.org.uk/help-and-advice/lost-found-and-feral-cats/lost-found-and-feral-cats&lt;/span&gt; &lt;span class="nn"&gt;"Lost &amp;amp; found cats"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But that title attribute is &lt;em&gt;not&lt;/em&gt; currently rendered by our customer render hook. Let's fix that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;{{ $u := urls.Parse .Destination }}
{{ $yourDomain := "localhost" }}
{{ $class := "internal" }}

{{ if not (strings.ContainsNonSpace $u.Hostname)}}
    {{ $class = "relative" }}
{{ else }}
    {{ if not (compare.Eq $u.Hostname $yourDomain) }}
        {{ $class = "external" }}
        {{ if (compare.Eq $u.String .Text) }}
            {{ $class = "external implied"}}
        {{ end }}
    {{ end }}
{{ end }}

&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"{{ .Destination | safeURL }}"&lt;/span&gt; 
&lt;span class="err"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;with&lt;/span&gt; &lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Title&lt;/span&gt;&lt;span class="err"&gt;}}&lt;/span&gt;&lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"{{ . }}"&lt;/span&gt;&lt;span class="err"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;end&lt;/span&gt; &lt;span class="err"&gt;}}&lt;/span&gt; 
&lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"{{ $class }}"&lt;/span&gt; 
&lt;span class="na"&gt;data-domain=&lt;/span&gt;&lt;span class="s"&gt;"{{ $u.Hostname }}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"link-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ .Text | safeHTML }}&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"hostname-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ $u.Hostname }}&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We've simply tested to see if the &lt;code&gt;.Title&lt;/code&gt; variable exists, and if it does, add the title attribute. Our link now renders like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://www.cats.org.uk/help-and-advice/lost-found-and-feral-cats/lost-found-and-feral-cats"&lt;/span&gt; 
   &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Lost &amp;amp;amp; found cats"&lt;/span&gt; 
   &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"external"&lt;/span&gt; 
   &lt;span class="na"&gt;data-domain=&lt;/span&gt;&lt;span class="s"&gt;"www.cats.org.uk"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"link-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Custom text, deep link, with title&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"hostname-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;www.cats.org.uk&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not a big deal, but what's nice is that you can use the existence of the title attribute to give some of those deeplinks a bit more context, without showing the whole URL. We add this to the end of our CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="nd"&gt;::after&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;'('&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;')'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and we &lt;em&gt;get&lt;/em&gt; titles. Which you can style if you want. It also gives you the title on when the mouse hovers over the link. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsgp5jdb98mj0hjipcvc6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsgp5jdb98mj0hjipcvc6.png" alt="Screenshot, now showing content from the title attribute"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  One more thing
&lt;/h2&gt;

&lt;p&gt;Last of all, I want my external links to always open in a new tab, so we can add a &lt;code&gt;target&lt;/code&gt; attribute to our link. And that is the solution!&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;/layouts/_default/_markup/render-link.html&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;{{ $u := urls.Parse .Destination }}
{{ $yourDomain := "localhost" }}
{{ $class := "internal" }}
{{ $target := "" }}

{{ if not (strings.ContainsNonSpace $u.Hostname)}}
    {{ $class = "relative" }}
{{ else }}
    {{ if not (compare.Eq $u.Hostname $yourDomain) }}
        {{ $class = "external" }}
        {{ $target = "_blank" }}
        {{ if (compare.Eq $u.String .Text) }}
            {{ $class = "external implied"}}
        {{ end }}
    {{ end }}
{{ end }}

&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"{{ .Destination | safeURL }}"&lt;/span&gt; 
&lt;span class="err"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;with&lt;/span&gt; &lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Title&lt;/span&gt;&lt;span class="err"&gt;}}&lt;/span&gt;&lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"{{ . }}"&lt;/span&gt;&lt;span class="err"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;end&lt;/span&gt; &lt;span class="err"&gt;}}&lt;/span&gt; 
&lt;span class="na"&gt;target=&lt;/span&gt;&lt;span class="s"&gt;"{{ $target }}"&lt;/span&gt;
&lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"{{ $class }}"&lt;/span&gt; 
&lt;span class="na"&gt;data-domain=&lt;/span&gt;&lt;span class="s"&gt;"{{ $u.Hostname }}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"link-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ .Text | safeHTML }}&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"hostname-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ $u.Hostname }}&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the final CSS...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;
&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="nc"&gt;.internal&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="nc"&gt;.relative&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;.hostname-text&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="nc"&gt;.external&lt;/span&gt;&lt;span class="nd"&gt;:not&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;.implied&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;.hostname-text&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;none&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="nc"&gt;.external.implied&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;.link-text&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="nd"&gt;::after&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;'('&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s2"&gt;')'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Obviously, this is a little over-engineered, but it gives you a lot of flexibility to display links however you like.&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;

&lt;p&gt;If you found this useful, or have feedback please drop me a line &lt;a href="https://mastodon.social/@toychicken/113249975233953921" rel="noopener noreferrer"&gt;@toychicken&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, if you too love cats, make a donation to the &lt;a href="https://www.cats.org.uk/donate" rel="noopener noreferrer"&gt;Cats protection league&lt;/a&gt; today. 🐈‍⬛&lt;/p&gt;

</description>
      <category>hugo</category>
      <category>css</category>
      <category>html</category>
    </item>
  </channel>
</rss>
