Table Of Contents
Introduction Link to heading
Some time ago I added MVP referral codes as query parameters to outgoing links to Microsoft websites in my blog posts. I had to go through all of my blog posts to find links to Microsoft websites and add them manually. I found this rather boring, so I wanted to automate this! By automating this process I will save time and effort, especially because any future references to those Microsoft domains will contain these query parameters automatically.
And while I was updating all these links, I realized that a lot of my links didn’t open a new tab; they would actually navigate the user away from my site. I don’t like that behaviour for all of my links, so I wanted to fix this.
So, In this blog post I will share how this is set up so you can use this for your own website! I built it in a generic way, so this will work with any domain and all query parameters.
Approaching the problem Link to heading
Identifying the problem Link to heading
Opening links in a new tab Link to heading
When I was working on my blog post about using Bogus to create seed data for EF Core, I stumbled upon a small issue with how my links are generated.
I use Markdown with the default Goldmark renderer to write these blog posts because I find it very convenient. Markdown allows you to use the following syntax to create a link: [Link text]( https://example.com).
Clicking on such a link would normally open the link in the current tab which means you leave the current website. This can be very annoying if you are reading a blog post and want to learn more about something and want to continue reading as well. So, we want to open links to other websites in a new tab.
Markdown supports HTML, so I could simply stop using the Markdown syntax and use <a href="https://example.com" target="_blank">Link text</a>
instead. But I find that this makes my blog posts messy and more difficult to write. I could also use a
Custom shortcode to clean that up, but it’s still a bit messier than the markdown syntax.
I wanted to fix this problem by just changing the way Markdown renders my links. So, how can we do that?
Adding query parameters automatically for specific domains Link to heading
In case the problem may not be very clear yet, I mean something like this: Imagine that I want to add ?hello=world
to all outgoing https://example.com
and https://something.com
links. Not only would I need to update all my blog posts by hand, I would also need to remember to do this for all new blog posts and future edits.
If we look into solving this problem, it seems quite similar to the previous one; I don’t want to do this manually, and I don’t want to create shortcodes. It would be best if I could change the link renderer itself.
Looking for the solution Link to heading
I quickly found others online who had the same ‘opening links in a new tab’ problem. However, I still needed to modify this code to modify these links with custom query parameter.
Luckily, ChatGPT came to my rescue because I had to write some Go Templates for this, and I had no experience with this. So if you have any feedback on the code below, let me know!
The solution Link to heading
It’s time to present the solution!
You need to create a
render-link.html
file inlayouts/_default/_markup/
folder, which will override the default link renderer behaviour.Put the following code in it.
<!-- Put a list of your domains here --> {{ $domains := slice "example.com" "something.com" }} <!-- Put your query parameter(s) here --> {{ $param := "hello=world" }} {{ $destination := .Destination }} {{ $found := false }} {{ range $domains }} {{ if not $found }} {{ $domain := . }} {{ $splitDest := split $destination "://" }} {{ $splitPath := split (index $splitDest 1) "#" }} {{ $splitPathFragments := split (index $splitPath 0) "?" }} {{ $splitDomain := split (index $splitPathFragments 0) "/" }} {{ $found = hasPrefix (index $splitDomain 0) $domain }} {{ if $found }} {{ $query := index $splitPathFragments 1 }} {{ $path := printf "%s?%s" (index $splitPathFragments 0) $param }} {{ $fragment := index $splitPath 1 }} {{ if ne $fragment nil }} {{ $destination = printf "%s://%s#%s" (index $splitDest 0) (printf "%s%s" $path "") $fragment }} {{ else }} {{ $destination = printf "%s://%s" (index $splitDest 0) $path }} {{ end }} {{ end }} {{ end }} {{ end }} <a href="{{ $destination | safeURL }}"{{ with .Title}} title="{{ . }}"{{ end }}{{ if strings.HasPrefix $destination "http" }} target="_blank"{{ end }}>{{ .Text }}</a>
The result: If you type the following markdown [Link text](
https://example.com), you will be presented with the following HTML: <a href="https://example.com?hello=world" target="_blank">Link text</a>
. If you had any existing query parameters in your original markdown link, the new query parameter will be appended. The same goes for the hash.
Explanation Link to heading
The code does the following:
- Defines a list of domain names and assigns it to a variable
$domains
. - Defines a query parameter with a key-value pair and assigns it to a variable
$param
. - Assigns the current page’s destination URL to a variable
$destination
. - Initializes a boolean variable
$found
to false. - Loops through each domain in the
$domains
list. - If
$found
is false, it performs the following operations:- Assigns the current domain to a variable
$domain
. - Splits the
$destination
URL into its components (scheme, path, fragment) and assigns them to variables$splitDest
,$splitPath
, and$fragment
. - Extracts the path fragments from the
$splitPath
variable and assigns them to$splitPathFragments
. - Extracts the domain name from the path fragments and assigns it to
$splitDomain
. - Checks if the domain name starts with the current
$domain
using hasPrefix function and assigns the result to$found
.
- Assigns the current domain to a variable
- If
$found
is true, it modifies the URL by adding the query parameter$param
to the URL’s path.- If the URL has a fragment, it appends the modified path and fragment back to the URL.
- If the URL has no fragment, it appends only the modified path to the URL.
- Assigns the modified URL back to
$destination
.
- Outputs an anchor tag with the modified URL.
Finishing up Link to heading
If you have any questions or know of any improvements, let me know in the comments below!