Externe Links von Hugo in gesondertem Reiter öffnen lassen

20. September 2022

Vor Jahren habe ich meine Website Felsenstrand.de von Wordpress auf Hugo umgestellt. Mit der damaligen Konfiguration von Hugo hat der Leser beim Anklicken von Links meine Seite verlassen, da der Browser die dahinter stehende Seite im aktuellen Reiter geöffnet hat. Auf meiner Liste von Konfigurationsanpassungen hatte ich schon lange eingetragen, dieses Verhalten zu ändern. In diesem Artikel beschreibe ich, mit welchen Anpassungen ich das erreicht habe.

Was ist das Problem?

Das Web lebt davon, dass Webseiten aufeinander verweisen. Wenn der Leser einem Verweis folgt, dann stellt der Browser die neue Seite anstelle der vorherigen dar. Dabei verlässt der Leser dann unbewusst die ursprüngliche Website.

Ich als Autor möchte aber den Leser gerne etwas länger auf meiner Seite halten, damit die Artikel, die ich geschrieben habe, auch gelesen werden.

Wie sieht der Lösungsansatz aus?

Eine seit vielen Jahren umgesetzte Lösung sorgt dafür, dass der Browser nach außen führende Verweise in einem gesonderten Reiter öffnet. Dadurch kann der Leser dann sowohl die ursprüngliche als auch die neue Seite lesen.

Damit ich dieses Verhalten erreiche, muss ich eigentlich lediglich etwas HTML ergänzen.

Der Punkt ist nun, dass ich ja kein HTML schreibe, sondern Hugo nutze, das aus Markdown HTML erzeugt. Und nicht einmal das Markdown schreibe ich, sondern ich bin im Emacs unterwegs und bewege mich dort im Org-Mode.

Da ich sicherlich nicht das HTML für jeden Link von Hand ergänzen möchte, suche ich also einen Automatismus, der ausgehende Verweise entsprechend kennzeichnet. Glücklicherweise hat Hugo seit längerem dafür eine Lösung an Bord.

Und was musste ich nun machen?

Mit Version 0.62 ist sind die Hugo-Entwickler von der Komponente »Blackfriday« auf »Goldmark« umgestiegen, um HTML-Seiten zu erzeugen. Diese Komponente bietet die Möglichkeit, sich mit sogenannten »render hooks« in die Erzeugung von HTML »einzuklinken«.

Diese »hooks« werden dadurch umgesetzt, dass der Autor an der richtigen Stelle im Dateisystem ein Hugo-Template mit dem richtigen Namen ablegt. Dieses Template nutzt Hugo dann bei dem Erzeugen von HTML.

Die Dokumentation von Hugo zeigt anhand eines Beispiels, wie man ausgehende Verweise in einem gesonderten Reiter öffnen lassen kann. Dabei wird untersucht, ob ein Link mit einer Protokollangabe beginnt; wenn dem so ist, wird der Link als ausgehender Link gedeutet und so ausgezeichnet, dass der Browser ihn in einem gesonderten Reiter öffnet.

Damit wäre ich eigentlich fertig, wenn ich alle Verweise innerhalb von Felsenstrand.de als relative Verweise ohne Protokollangabe notiert hätte.

Wäre.

»Aus historischen Gründen« habe ich eine Reihe von internen Verweisen, die voll qualifiziert den vollständigen Verweis enthalten. Das hat auch damit zu tun, dass ich meine unter WordPress veröffentlichten Artikel mit einem Markdown-Exporter vor meinem Umstieg auf Hugo gerettet hatte. Und meiner Faulheit, mir die Zeit zu nehmen, um mit einem kleinen Skript die Verweise ein für alle mal glattzuziehen.

Deswegen kann ich das Beispiel aus der Hugo-Dokumentation nicht einfach so übernehmen, sondern muss es leicht erweitern. Ich habe es um eine weitere Abfrage ergänzt, ob der Link denn nicht etwa auf einen meiner Artikel verweist.

Lange Rede kurze Sinn: Hier ist das Hugo-Template namens layouts/_default/_markup/render-links.html.

<a href="{{ .Destination | safeURL }}"{{ with .Title}} title="{{ . }}"{{ end }}{{ if strings.HasPrefix .Destination "http" }} {{ if not (strings.HasPrefix .Destination "https://felsenstrand.de") }} target="_blank" rel="noopener"{{ end }}{{ end }}>{{ .Text | safeHTML }}</a>

Für die Kernaussage dieses Artikels ist das Attribut target wichtig, das dann zu dem gewünschten Verhalten führt.

Dieses Verhalten öffnet allerdings eine Sicherheitslücke. Die Verwendung des Attributs rel ist in diesem Zusammenhang wichtig, um diese Lücke zu schließen.

Weiterlesen

Wenn du mehr über die »render hooks« erfahren möchtest, empfehle ich dir die Hugo-Dokumentation dazu. Dort habe ich auch das Beispiel gefunden, das ich ergänzt habe.

Die Verhaltensänderung des Browsers erreiche ich dadurch, dass ich das Attribut names target setzte. Mehr zu diesem Attribut findest du zum HTML-Standard bei Mozdev.

Zum standardkonformen Verhalten eines Webbrowsers gehört es mittlerweile, dass die angesprochene Sicherheitslücke implizit gleich geschlossen wird. Welche Browserversionen sich schon so verhalten, findest du in der Browsermatrix auf Mozdev.

Ausführliche Informationen zu den erwähnten Sicherheitsaspekten findest du unter der Beschreibung zu Reverse Tabnapping von OWASP und den entsprechenden Eintrag in dessen HTML5 Security Cheat Sheet dazu.

Veröffentlicht:
20. September 2022
Länge:
Etwa 4 Minuten Lesedauer, 678 Wörter
Tags:
Felsenstrand Hugo HTML OWASP
Siehe auch:
Von verschwundenen Webseiten und stabilen Webadressen