eallion

大大的小蜗牛

机会总是垂青于有准备的人!
mastodon
github
twitter
steam
telegram
keybase
email

Hugo External Link Redirect Prompt Page

Preface#

Recently, I saw a blog post by "Uncle Qin" titled "Website Restart" mentioning that due to expired domain names left by others in blog comments linking to adult websites, he faced issues related to adult content. This shows that in the current internet environment in mainland China, such minor offenses are being cracked down on more strictly.

For compliance and self-censorship, I did two things for my blog: first, I migrated the comment system to Giscus, which raised the threshold for comments and put them in a semi-closed state; second, I cleaned up some links in the blog, allowing the remaining links to redirect through a landing page. Coincidentally, I saw "Kongbai" update his blog "HUGO External Link Redirect to Intermediate Page", and I directly copied the style, completing one item on my Todo list.

PS: I believe a serious personal website can be filed for record. But if you want to do something less serious, what you need is complete identity isolation, not just avoiding registration while exposing many related cross-identity information. No paternalism, listen if you want.

Definition#

External Link: Full name is external link, also known as import link. It refers to links from other websites on the internet that lead to your own website. Hereinafter referred to as "external link."

Creating Redirect Pages with 3 Files#

My design approach is somewhat different from "Kongbai's" first version of JS. I utilized Hugo's built-in template _markup's render-link.html to base64 encode external links during Hugo's build process, fully leveraging the features of SSG.

1. Create or Modify render-link.html#

_markup/render-link.html is Hugo's built-in template for rendering links. If the theme used by the blog does not have a custom render-link.html, you need to create this file yourself. If the theme has already customized link rendering, you can directly modify this file. The file is located in the layouts directory at the root of the Hugo project:

layouts/
└── _default/
    └── _markup/
        ├── render-codeblock-bash.html
        ├── render-codeblock.html
        ├── render-heading.html
        ├── render-image.html
        ├── render-image.rss.xml
        └── render-link.html    # < --- This file

The content of the file I used:

$domainList acts as a whitelist.

{{- $domainList := slice "www.eallion.com" "github.com" "twitter.com" -}}
{{- $parsedDestination := urls.Parse .Destination -}}
{{- $host := $parsedDestination.Host -}}
{{- $matched := false -}}
{{- range $domainList -}}
    {{- if strings.HasSuffix $host . -}}
        {{- $matched = true -}}
        {{- break -}}
    {{- end -}}
{{- end -}}
{{- if $matched -}}
    <a href="/go/?target={{ .Destination }}" target="_blank" rel="noopener noreferrer">{{ .Text | safeHTML}}</a>
{{- else -}}
    <a href="/go/?target={{ .Destination | base64Encode }}" target="_blank" rel="noopener noreferrer">{{ .Text | safeHTML}}</a>
{{- end -}}

PS: For the DoIt theme, you only need to modify layouts/partials/plugin/link.html.

Tips: Using render-link.html allows the blog to open in a new window, i.e., target="_blank". Many Asian users are searching for this trick.

2. Create Layout Template go.html#

Create a page template, such as go.html, located in the layouts/_default/go.html directory of the Hugo project. The simplest way is to copy single.html and rename it to go.html.

layouts/
└── _default/
    └── go.html    # < --- This file

Here is my content, placing HTML, CSS, and JS in the same page for easier maintenance. Besides ensuring that the <div class="redirect-all"> element is in the correct position in your template, it is basically ready to use.

{{- define "title" }}{{ .Title }} - {{ .Site.Title }}{{ end -}}

{{- define "content" -}}
    {{- $params := .Scratch.Get "params" -}}
    <style>
        .redirect-all {
            position: relative;
            box-shadow: rgba(0, 0, 0, 0.25) 0px 25px 50px -12px;
            border-radius: 10px;
            color: #666;
            word-break: break-all;
            max-width: 800px;
            height: 400px;
            text-align: center;
            font-size: 0.85rem;
            overflow: hidden;
            margin: 100px auto 0;
            background: #fff url(/assets/images/redirect/redirect-light.webp) no-repeat center center / cover;
            @include breakpoint('small') {
                aspect-ratio: 2 / 1;
                height: auto;
            }
        }

        .redirect-nrong {
            position: absolute;
            bottom: 0;
            left: 0;
            right: 0;
            padding: 1.5rem 1rem
        }

        .redirect-title {
            font-size: 1.25rem;
            font-weight: bold;
            color: #222;
            margin-bottom: 0.5rem;
        }

        .redirect-info {
            margin-top: 6px;
        }

        .redirect-tis {
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 20px;
            margin-top: 1rem;
            margin-bottom: 2px;
            flex-wrap: wrap;
        }

        .redirect-button {
            display: flex;
            align-items: center;
            border-radius: 3px;
            border: none;
            background: #006bee;
            height: 32px;
            padding: 0 14px;
            cursor: pointer;
            outline: 0;
        }

        .redirect-button a {
            color: #fff !important;
        }

        [theme=dark] .redirect-all {
                background: #fff url(/assets/images/redirect/redirect-dark.webp) no-repeat center center / cover;
                color: #999;
            }

        [theme=dark] .redirect-title {
                color: #ddd;
            }
    </style>

    <div class="page single special">

        {{- /* Content */ -}}
        <div class="content" id="content">
            <div class="redirect-all">
                <div class="redirect-nrong">
                    <div class="redirect-title">You are about to leave {{ .Site.Title }} and redirect to the following external link</div>
                    <a href="" target="_self" rel="noopener noreferrer" id="redirect-link"><span id="redirect-link">Redirect target not specified.</span></a>
                    <div class="redirect-info">Please identify whether this link is safe, and pay attention to your account and property safety.</div>
                    <div class="redirect-tis">
                        <div class="redirect-button"><a href='' target="_self" id='direct-link' rel="noopener noreferrer">Go Now</a></div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script>
        const params = new URLSearchParams(window.location.search);
        const encodedTarget = params.get('target');
        const target = atob(encodedTarget); // Use atob for Base64 decoding

        if (target) {

            const decodedTarget = decodeURIComponent(target);

            document.getElementById('direct-link').href = decodedTarget;
            document.getElementById('redirect-link').textContent = '' + decodedTarget; // Display the original address in the new element
            document.getElementById('redirect-link').href = decodedTarget;

        } else {
            const redirectMessageElement = document.getElementById('redirect-link');
            redirectMessageElement.textContent = 'Redirect target not specified.';
        }
        </script>
{{- end -}}

3. Create go.md to Call the Template#

In the content directory of the Hugo project, create a file named go.md, where go will be the link path for the redirect page. The Front matter of the go.md file should select the corresponding template you just created; if the template name is go.html, then layout or type should both be set to go.

---
title: "Redirect"
layout: "go"
type: "go"
... ...
---
4. Background Image#

Place the background images in the static directory:
or in a location you can reference correctly, such as a CDN, and modify the background url in the <style>. Additionally, you need to adapt to your theme's Dark mode.

  • static/assets/images/redirect/redirect-light.webp
  • static/assets/images/redirect/redirect-dark.webp

Other Considerations#

This method can only render all Markdown content documents in this blog, i.e., .md files in the content directory. If you are used to using {{ Shortcodes }} for posting, or if the page has custom HTML links, you need to make the link path base64 compatible yourself. This template can parse links like href="/go/?target={{ base64Encode }}" within the blog, excluding the whitelist.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.