hugo-nip-05.md (2801B)
1 +++ 2 draft = false 3 date = 2025-07-16T14:57:56-03:00 4 title = "Hugo and nip-05" 5 description = "Setup nostr nip-05 with a Hugo site." 6 slug = "" 7 authors = ["Jack Mordaunt"] 8 tags = ["hugo", "nostr"] 9 categories = ["development"] 10 externalLink = "" 11 series = [] 12 +++ 13 14 [nip-05](https://nostr.how/en/guides/get-verified) is a convenience for identifying users on nostr such as `mordaunt@jackmordaunt.com`, which is 15 shorter and more memorable than a {{< tooltip tip="npub14l0387z0ejfmnn3j38nnalg5p57952d84aqakqguhzx7p7pns2vqg3x78w" >}}raw npub{{< /tooltip >}}. 16 17 It works by making a `GET` request at `jackmordaunt.com/.well-known/nostr.json` and extracting the 18 public keys from the JSON response. 19 20 This quick guide will show you how to host your own with a Hugo site. 21 22 ### Add your configuration. 23 24 Inside your `hugo.toml`, add: 25 26 ```toml 27 [[params.nostr]] 28 name = "name" 29 npub = "npub..." 30 ``` 31 32 If you have multiple names you want to host you can add them. 33 34 ```toml 35 [[params.nostr]] 36 name = "name1" 37 npub = "npub..." 38 [[params.nostr]] 39 name = "name2" 40 npub = "npub..." 41 [[params.nostr]] 42 name = "name3" 43 npub = "npub..." 44 ``` 45 46 I've picked `nostr` as the subkey, but you can structure this config however you like. 47 48 ### Define the output type. 49 50 ```toml 51 [outputFormats.nostrjson] 52 mediaType = "application/json" 53 baseName = "nostr" 54 path = ".well-known" 55 isPlainText = true 56 permalinkable = true 57 notAlternative = true 58 59 [outputs] 60 home = ["HTML", "nostrjson"] 61 ``` 62 63 This output type tells Hugo that we want to render a JSON file. 64 `nostrjson` is just the name of this type, you can pick whatever name you like. 65 66 Read more about output formats [here](https://gohugo.io/configuration/output-formats). 67 68 ### Add the JSON template 69 70 ```html 71 {{ $nostr := .Site.Params.nostr }} 72 { 73 "names": { 74 {{- range $k, $v := $nostr }} 75 "{{ $v.name }}": "{{ printf "%x" $v.npub }}"{{ if not (eq $k (sub ($nostr | len) 1)) }},{{ end }} 76 {{- end }} 77 } 78 } 79 ``` 80 81 This template iterates all nostr configurations under `.Site.Params.nostr` and renders a key-value entry 82 in the JSON object. The npub is hex encoded because that is the expected format. 83 84 The complex conditional at the end is simply for placing the commas correctly. 85 86 ### Build it 87 88 `hugo build` and verify that the root of the output under `public` contains `.well-known/nostr.json` with 89 the correct content! 90 91 When you publish the site you should be able to get the JSON from doing a `GET` for `.well-known/nostr.json`. 92 93 Lastly, you can specify relays that you are likely to be found on. You'll have to adjust the template. 94 95 ```html 96 97 { 98 "names": { 99 "YOUR_NOSTR_NAME": "YOUR_NOSTR_PUBLIC_KEY_IN_HEX_FORMAT" 100 }, 101 "relays": { 102 "YOUR_NOSTR_PUBLIC_KEY_IN_HEX_FORMAT": [ 103 "wss://relay.one", 104 "wss://relay.two", 105 ... 106 ] 107 } 108 } 109 ```