Skip to main content

Sources pages for YouTube videos

srcnexus sources publishes the sources behind your videos as a small website:

  • One page per video listing every source it uses — numbered, with publisher, author, date, a note, and a timestamp link to the moment in the video where it is used.
  • One index listing every video, with a search box that looks through every source of every video, not only the titles, and shows which sources matched.
  • Filters — by year on the index; by kind (article, paper, book…) and by website on a video page.
  • Shareable filtered links — search and filters are kept in the address (?q=…, ?year=…, ?kind=…, ?site=…), and every source has its own anchor (#s-4), so you can link to exactly what you mean in a reply.

You write one short YAML file per video. The CLI renders the site with a template and deploys it to your SrcNexus site. A video's page lives at:

https://<username>.srcnexus.app/<project>/<video-id>/

That is the link you put in the video's description.

The pages are plain HTML and CSS with a little JavaScript for search: they load fast on a phone (where most people arrive from a YouTube description), work in light and dark mode, and still list everything with JavaScript off.

Quick start​

You need the CLI and a SrcNexus account (srcnexus signup, or srcnexus login if you have one).

mkdir my-sources && cd my-sources

# 1. Create the site file and the sources/ folder
srcnexus sources init --channel-name "My Channel" --channel-url https://www.youtube.com/@<your-handle> --handle @<your-handle>

# 2. Add a video
srcnexus sources new how-tides-work --title "How tides work" --youtube https://youtu.be/<video-id>

# 3. Fill in sources/how-tides-work.yaml, then look at it locally
srcnexus sources preview # http://127.0.0.1:4173 — re-renders on every reload

# 4. Publish, and get the link for your video description
srcnexus sources deploy
srcnexus sources url how-tides-work

Want to see it before writing anything? srcnexus sources preview --sample serves a sample channel with five videos.

Folder layout​

my-sources/
srcnexus.sources.yaml the site: your channel, the template, the project
sources/
how-tides-work.yaml one file per video
why-ice-floats.yaml
thumbs/ optional — local images you point at (any folder name)
my-template/ optional — your own template
  • The file name is the video id, and the video id is the page's address: sources/how-tides-work.yaml becomes …/<project>/how-tides-work/. Ids are lower-case letters, digits and hyphens (up to 63 characters, starting with a letter or digit).
  • Video files may be .yaml, .yml or .json. Two files with the same id (a.yaml and a.json) are an error.
  • build writes the site to _site/ in this folder unless you pass --out.

srcnexus.sources.yaml​

project: sources            # SrcNexus project the site deploys to
template: plain # a built-in template, or ./path/to/your/template
title: Sources
description: Every claim in our videos, and where it comes from.
lang: en
accent: "#e4572e" # optional
channel:
name: Example Channel
url: https://www.youtube.com/@<your-handle>
handle: "@<your-handle>"
avatar: ./thumbs/avatar.png
links:
- label: YouTube
url: https://www.youtube.com/@<your-handle>
- label: Newsletter
url: https://example.com/newsletter
FieldRequiredDefaultDescription
projectsourcesThe SrcNexus project the site deploys to — part of every URL. Lower-case letters, digits and hyphens. Created on the first deploy.
templateplainA built-in template id, or a path to your own template folder, relative to this file (./my-template).
titleSourcesThe site's heading.
descriptionOne line under the heading.
langenThe pages' lang attribute.
accentA CSS colour the templates use for links and highlights: #e4572e, a colour name, or rgb() / hsl() / oklch(). Quote hex values — # starts a YAML comment.
channel.nameyesYour channel's name.
channel.urlYour channel's address (http or https).
channel.handle@yourhandle — quote it in YAML.
channel.avatarYour channel picture, in any of the three image forms.
linksOther links shown on the site: a list of {label, url}.

init writes this file for you. It fills in description with a default line and adds a YouTube link when you pass --channel-url; edit it afterwards for the rest.

Video files​

title: How tides work
youtube: https://youtu.be/<video-id>
published: 2026-10-20
description: Why there are two high tides a day, and why they move.
thumbnail: ./thumbs/how-tides-work.jpg # optional — default: the YouTube thumbnail
sources:
- title: Tides and water levels
url: https://oceanservice.noaa.gov/education/tutorial_tides/
publisher: NOAA
kind: gov
at: "2:41"
note: The diagram at 2:41 is redrawn from figure 3.
- title: "Hot mixing: Mechanistic insights into the durability of ancient Roman concrete"
url: https://www.science.org/doi/10.1126/sciadv.add1602
publisher: Science Advances
author: Seymour, L. M. et al.
date: 2023-01-06
kind: paper
archive: https://web.archive.org/web/2024/https://www.science.org/doi/10.1126/sciadv.add1602
- MIT News — Riddle solved https://news.mit.edu/2023/roman-concrete-durability-lime-casts-0106
FieldRequiredDescription
titleyesThe video's title.
youtubeA YouTube link (youtu.be/…, watch?v=…, /shorts/…, /live/…, /embed/…) or the bare 11-character video id. Used for the thumbnail, the "watch" link and the timestamp links.
publishedYYYY-MM-DD. The index is newest first; videos without a date are listed last.
descriptionA line or a paragraph about the video.
thumbnailOverrides the YouTube thumbnail — see the three image forms.
sourcesThe list of sources, in the order the video uses them.
sectionsInstead of sources: groups with headings. Use one or the other, not both.

Sources​

FieldRequiredDescription
titleyesThe article, paper or book's title.
urlyesWhere it is (http or https). The site shows its domain: en.wikipedia.org → wikipedia.org.
publisherWho published it: NOAA, The New York Times.
authorWho wrote it.
dateWhen it was published — YYYY-MM-DD is shown as 6 Jan 2023.
noteA line about how the video uses it.
kindOne of article, paper, book, video, archive, data, gov, other (default other). Drives the kind filter.
atWhere in the video it is used: 4:35, 1:02:03, or seconds (275). Becomes a link to that moment on YouTube. Quote it in YAML ("4:35").
archiveA web.archive.org (or other) copy, in case the original moves.

Shorthand: a source can be a single line — the title, then the URL at the end. It becomes a source of kind other with no other fields. A bare URL works too; the title is then its host name.

sources:
- Roman concrete — Wikipedia https://en.wikipedia.org/wiki/Roman_concrete
- https://www.gutenberg.org/ebooks/20239

Sections​

Group sources under headings with sections. Numbering runs on across sections, in film order.

title: The day a wave of molasses swept through Boston
youtube: https://www.youtube.com/watch?v=<video-id>
published: 2026-10-20
sections:
- heading: The tank
sources:
- title: Boston Molasses Disaster
url: https://en.wikipedia.org/wiki/Boston_Molasses_Disaster
kind: article
at: "0:42"
- heading: The wave
sources:
- title: "Molasses Flood: Scientists explain why it was so deadly"
url: https://www.nytimes.com/2016/11/26/science/boston-molasses-flood-science.html
publisher: The New York Times
kind: article
at: "4:35"

Thumbnails and the channel avatar​

A video's thumbnail and the channel's avatar take an image in any of three forms:

FormExampleWhat happens
An image URLhttps://example.com/thumb.jpgUsed as-is.
A local file./thumbs/how-tides-work.jpgRelative to the site folder (absolute paths work too). The file is copied into the site (under media/) and uploaded with it. .jpg, .jpeg, .png, .webp, .gif or .avif, up to 10 MB.
A YouTube link or idhttps://youtu.be/<video-id> or <video-id>That video's YouTube thumbnail.

When a video has no thumbnail, its page uses the video's own YouTube thumbnail (from youtube). A video with neither shows no image; every template handles that.

A value that is not a URL, an existing file, or an 11-character YouTube id is an error that names the path it looked for.

Commands​

Every command works on the current folder; pass --dir <path> to point at another one. All except preview take --json.

sources init​

Create srcnexus.sources.yaml and the sources/ folder.

srcnexus sources init --channel-name "My Channel" --channel-url https://www.youtube.com/@<your-handle> --handle @<your-handle> --template cards
OptionDescription
--dir <path>Folder to create the site in (default: .)
--channel-name <name>Your channel name — asked for in a terminal if missing, required otherwise
--channel-url <url>Your channel URL
--handle <handle>Your channel handle, e.g. @mychannel
--template <name|path>Built-in template name or a template folder (default: plain)
--project <name>SrcNexus project the site deploys to (default: sources)
--title <title>Site title (default: Sources)
--forceOverwrite an existing srcnexus.sources.yaml
--jsonPrint the result as JSON

sources new <video-id>​

Create sources/<video-id>.yaml with the fields filled in and the rest commented out.

srcnexus sources new how-tides-work --title "How tides work" --youtube https://youtu.be/<video-id> --published 2026-10-20
OptionDescription
--dir <path>The sources site folder (default: .)
--title <title>Video title (default: the id)
--youtube <link>YouTube link or video id
--published <date>Publish date, YYYY-MM-DD (default: today)
--jsonPrint the result as JSON

sources templates​

List the built-in templates. See Sources templates.

srcnexus sources templates

sources eject <template> [dest]​

Copy a built-in template into a folder to make your own (default folder: ./template-<id>). See Custom sources templates.

srcnexus sources eject plain ./my-template

sources check​

Validate the site file, every video file and the template, render everything in memory, and list warnings. Uploads nothing.

srcnexus sources check

Errors name the file and the field (sources/how-tides-work.yaml sources[3]: "at" must be like 4:35 or 1:02:03). Warnings flag a video with no sources yet, no youtube link, no published date, or the same URL listed twice.

OptionDescription
--dir <path>The sources site folder (default: .)
--template <name|path>Use this template instead of the one in the site file
--sampleUse the bundled sample site (to try a template)
--jsonPrint the result as JSON

sources build​

Render the site into a folder. Nothing is uploaded. The output folder is emptied first.

srcnexus sources build --out ./public
OptionDescription
--dir <path>The sources site folder (default: .)
--out <path>Output folder (default: <dir>/_site)
--template <name|path>Use this template instead of the one in the site file
--sampleUse the bundled sample site (to try a template)
--jsonPrint the result as JSON

sources preview​

Serve the site at http://127.0.0.1:4173. Every request re-renders from your files, so an edit — to a video file or to a template — shows on the next reload. An error in your files is shown in the browser.

srcnexus sources preview
srcnexus sources preview --sample --template table # try a template on sample data
OptionDescription
--dir <path>The sources site folder (default: .)
--template <name|path>Use this template instead of the one in the site file
--sampleUse the bundled sample site (to try a template)
--port <n>Port (default: 4173)

sources deploy [video-ids...]​

Render and upload the site to the project named in srcnexus.sources.yaml (created on first deploy). You must be logged in.

srcnexus sources deploy                          # every page
srcnexus sources deploy how-tides-work # one video's page, plus the index
srcnexus sources deploy how-tides-work why-ice-floats
OptionDescription
--dir <path>The sources site folder (default: .)
--jsonPrint the result as JSON
  • Deploys merge. Pages you do not send stay as they are on the site.
  • deploy <ids> uploads only those videos' pages, plus the index, the template's assets/, the channel avatar, and those videos' own thumbnail files. Use it after adding or changing one video — it is faster, and the index always comes along so the new video is listed and searchable.
  • With no ids, every page is uploaded.
  • An id with no sources/<id>.yaml is an error, and nothing is uploaded.
  • Deploy always uses the template named in the site file.
  • Pages are cached: after a deploy, a page can take a few minutes to refresh everywhere.

sources url [video-id]​

Print the link to the index, or to one video's page — ready to paste into the video's description. You must be logged in (the link contains your username).

srcnexus sources url                    # https://<username>.srcnexus.app/sources/
srcnexus sources url how-tides-work # https://<username>.srcnexus.app/sources/how-tides-work/

--json for scripts and AI agents​

Every sources subcommand except preview takes --json. It prints one JSON object on stdout and nothing else — no spinners, no prompts — so a script or an AI agent can read the result. Success has "ok": true; any error becomes {"ok": false, "error": "…"} with exit code 1.

srcnexus sources deploy how-tides-work --json
{
"ok": true,
"project": "sources",
"template": "plain",
"url": "https://your-name.srcnexus.app/sources/",
"pages": [
{ "id": "how-tides-work", "url": "https://your-name.srcnexus.app/sources/how-tides-work/" }
],
"files": 4
}
srcnexus sources check --json
{
"ok": true,
"template": "plain",
"videos": 5,
"sources": 140,
"pages": 8,
"warnings": [
"coming-soon: no sources yet",
"tunguska: no \"youtube\" link"
]
}

What each command returns:

CommandFields besides ok
initfile, videosDir
newfile
templatestemplates: [{id, name, description}]
ejectdir
checktemplate, videos, sources, pages, warnings[]
buildout, template, files[]
deployproject, template, url, pages: [{id, url}], files
urlurl

A typical agent loop: write or edit sources/<id>.yaml, run check --json until it is clean, deploy <id> --json, and put pages[0].url in the video's description. An account can be made the same way — see signup.