Discover Reference Guide

↩ Up


The supported way to integrate discover with your website is with hugo. It’s still possible to set up discover without hugo but will require a little more effort until a script is made.

How It Works

Any peer can host an html snippet which is their preview banner. This “profile card” will be displayed on other peer’s sites who want to share your work. Cross origin resource sharing will be enabled.

Any peer can have one or more lists of previews which can be labeled by topic. The previews are loaded with htmx. Websites which do not yet support discover should not be added to your previews.

In either case, the setup is minimal and flexible.


Make Your Preview

This is optional. If you just want to setup a directory displaying previews, then go to the client setup section.

First, create your preview file.

mkdir static/.well-known && touch static/.well-known/discover

There’s up to four fields to fill in:

- Your website's url
- A short description (optional)
- Url to your profile picture
- The website's name

Copy and paste this html into static/.well-known/discover, and swap in your info.

<a href="" title="My description" >
    <img src="">
    <span>My Name</span>

Allow CORS

Copy and paste this nginx snippet into your website’s configuration. It will enable your web server to accept ajax requests.

location /.well-known/discover {
    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Headers' '*';
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain; charset=utf-8';
        add_header 'Content-Length' 0;
        add_header Vary Origin;
        return 204;
    if ($request_method = 'GET') {
	add_header 'Access-Control-Allow-Origin' '*' always;
	add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
	add_header 'Access-Control-Allow-Credentials' 'true';
	add_header 'Access-Control-Allow-Headers' '*';
	add_header Content-Type text/html;

Reload nginx:

systemctl reload nginx

If you want your site to be previewed but not have a directory, you may stop here.



Although discover is based on trust, there are some security measures we can put in place for peace of mind.

Copy and paste this nginx snippet into your website’s configuration.

# Change 'links' to the name of the page discover is on
location /links/ {
#   Blocks inline js. Prevents xss attacks. Change 'self' if you use third party js
    add_header 'Content-Security-Policy' "script-src 'self';";
#   Blocks inline css. Prevents trolling. May break things if you use inline css.
    add_header 'Content-Security-Policy' "style-src 'self';";

Reload nginx:

systemctl reload nginx


In hugo’s data directory, make a new folder for discover previews.

mkdir data/discover && cd data/discover

Now make a new toml file (the name is unimportant) to store previews on a certain topic. You can make as many files as you’d like.

topic = "Placeholder Sites"
previews = [

Go up to your hugo directory and download htmx.min.js (it’s 12kb gzip’d).

cd ../..
curl -o static/htmx.js


Copy and paste the following shortcode into layouts/shortcodes/discover.html.

<div id="discover">
<script src="/htmx.js"></script>
<link rel="stylesheet" href="/css/discover.css"></link>
<noscript><link rel="stylesheet" href="/css/no-js.css"></noscript>
{{ range }}
    <h3>{{ .topic }}</h3>
    {{ range .previews }}
        hx-get="https://{{ . }}/.well-known/discover"
    {{ end }}
{{ end }}
<em>Powered by <a href="">Discover</a></em>

Now you can call that shortcode which builds your directory from any content file. Just include this snippet:

{{< discover >}}


Here’s the css from the demo to get you started. Copy and paste into static/css/discover.css.

:root {
	/* Link Colors for Light Theme */
        --links: royalblue;
        --hover: navy;
	/* Directory Colors for Light Theme*/
        --dbg: #eee;
        --dfg: #ddd;
        --dhl: #ccc;
@media (prefers-color-scheme: dark) {
    :root {
	    --links: lightskyblue;
	    --hover: azure;
	    --dbg: #2c2c2c;
	    --dfg: #353535;
	    --dhl: #555;

#discover header,footer,h1,h2,h3,h4{font-family: c059, sans-serif}

#discover {
    padding: 1rem;
    background: var(--dbg);
    border-radius: 5px;
#discover h3 {text-align: center}
#discover img {
    max-width: 10rem;
    max-height: 10rem;
    border-radius: 10rem;
#discover ul {
    display: flex;
    flex-direction: row;
    align-items: flex-end;
    justify-content: flex-start;
    flex-wrap: wrap;
#discover li {list-style-type: none}
#discover li a {
    padding: 1rem;
    margin: 0.5rem;
    border-radius: 2px;
    display: flex;
    flex-direction: column;
    background: var(--dfg);
    min-height: 220px;
#discover li a:hover {background: var(--dhl);}
#discover li a span{
    color: var(--links);
    font-weight: bold;
    padding-top: 1em;
    max-width: 160px;
#discover a:hover{color: var(--hover)}

If js is disabled, we should not display the directory. Copy and paste the following into static/css/no-js.css

#discover {display:none}

That’s it!

It’s left as an excercise to those with a different ssg to write a plugin supporting the discover project specification. Reach out and your work may be shared here.