Contents

Locking articles in Hugo

Introduction

Sometimes, a specific article may have flaws or contain information that we don’t want everyone to see, but we still want the article to be accessible to a select group of people. This is where article passwords come in handy!

https://raw.githubusercontent.com/Josh-test-lab/website-assets-repository/refs/heads/main/posts/Locking%20articles%20in%20Hugo/lock%20the%20article.en.png
After locking the article, a password is required to continue viewing.

Achieving this effect is very simple and only requires modifying 3 files. If there are multilingual needs, translation keys need to be modified.

Modify single.html

Navigate to the website’s root directory and open the /layouts/posts/single.html file. Add the following content below {{- $params := .Scratch.Get "params" -}}.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
    <!--Page Password-->
    {{- $password := $params.password | default "" -}}
    {{- $promptKey := $params.promptKey | default "" -}}
    {{- if ne $password "" -}}
        <script>
            (function(){
                if({{ $password }}){
                    let pageViewPrompt = prompt({{ $promptKey }} || {{ T "passwordPrompt" }});
                    if (pageViewPrompt != {{ $password }}){
                        alert({{ T "passwordError" }});
                        if (history.length === 1) {
                            window.opener = null;
                            window.open('', '_self');
                            window.close();
                        } else {
                            history.back();
                        }
                    }
                }
            })();
        </script>
    {{- end -}}

It should look like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{{- define "title" }}{{ .Title }} - {{ .Site.Title }}{{ end -}}

{{- define "content" -}}
    {{- $params := .Scratch.Get "params" -}}

    <!--Page Password-->
    {{- $password := $params.password | default "" -}}
    {{- $promptKey := $params.promptKey | default "" -}}
    {{- if ne $password "" -}}
        <script>
            (function(){
                if({{ $password }}){
                    let pageViewPrompt = prompt({{ $promptKey }} || {{ T "passwordPrompt" }});
                    if (pageViewPrompt != {{ $password }}){
                        alert({{ T "passwordError" }});
                        if (history.length === 1) {
                            window.opener = null;
                            window.open('', '_self');
                            window.close();
                        } else {
                            history.back();
                        }
                    }
                }
            })();
        </script>
    {{- end -}}


...

Modify default.md

Next, go to the website’s root directory and open the /archetypes/default.md file. Add promptKey: "" and password: "". It should look like this:

1
2
3
4
5
6
7
title: "{{ replace .TranslationBaseName "-" " " | title }}"
subtitle: ""
date: {{ .Date }}
lastmod: {{ .Date }}
draft: true
promptKey: ""
password: ""

Modify Internationalization Language Files

Finally, navigate to the /i18n/your-language-code.toml file in the website’s root directory and add the translation key values. Below are examples using Traditional Chinese (zh-tw) and English (en).

zh-tw.toml

1
2
3
4
5
[passwordPrompt]
other = "本文章暫不公開,請輸入密碼進行觀看。"

[passwordError]
other = "密碼錯誤。"

en.toml

1
2
3
4
5
[passwordPrompt]
other = "This article is currently unpublished. Please enter the password to view it."

[passwordError]
other = "Incorrect password."

Usage

If the article requires a password, simply enter the password in the password: "" field of the article’s markdown file. For example, if the password is 123, enter password: "123". If the password is left as password: "", the article will be viewable without a password.

You can modify promptKey: "" to change the prompt message for entering the password. By default, "" uses the translation key in the translation file. If you want to change the prompt to "This article is private.", enter promptKey: "This article is private."

Conclusion

On a whim, I researched and developed a feature to lock articles in Hugo. At first, I thought it wouldn’t be very useful, but after using it, I found it incredibly convenient. I highly recommend giving it a try!

Environment

  • Hugo 0.144.2
  • LoveIt theme (version from GitHub on February 21, 2025)

References

License

Some content of this article is reproduced, adapted, and forwarded with the permission of the original author, Stilig, as referenced in the source. The rest of the content is original.

The content of this article is partially reproduced, adapted, and forwarded with the permission of the original author, Stilig, as referenced in the source. Authorized images.