nodsv0.1.0 Write a record
nods.to
  1. nods
  2. The package
  3. Write a record

Write a record

A record states who made a site and what it was made with. Every credit is drawn from one.

Designed and built by Marigold and Pocket MondayKiln, 2026. Design: Marigold. Build: Pocket Monday. Made with Five colours.
  • okvalidate found no issues.

The code for what is on screen

import { assertValid } from '@nodsto/record';

export const record = {
  project: { title: 'Kiln', year: 2026, url: 'https://kiln.example' },
  statement: 'Designed and built by {creators}',
  creators: [
    {
      name: 'Marigold',
      url: 'https://marigold.example',
      kind: 'studio',
      role: 'design',
      degree: 'lead',
    },
    {
      name: 'Pocket Monday',
      url: 'https://pocketmonday.example',
      kind: 'studio',
      role: 'development',
    },
  ],
  materials: [
    {
      kind: 'palette',
      name: 'Five colours',
      swatches: ['#1f2a44', '#c8553d', '#e9dcc3', '#7a8f6a', '#f2b84b'],
    },
  ],
};

assertValid(record);

Start with the project, a statement and the creators.

The statement is your wording and the client’s. It may use three slots, {creators}, {year} and {title}, or stay empty for names alone. Type a slot the record does not have into the statement above, such as {studio}, and the check says so.

Each creator is one entity with a name and a web address. A studio counts once, however many people work there. Its people go in members, which the record page prints and the footer leaves out.

Choose each role from the sixteen.

A role has a label for lists and a verb for a line that reads as a sentence. Add a degree of lead, equal or supporting where two creators share a role.

RoleIn a listOn a lineWhat it covers
designDesignDesigned byVisual and interaction design, layout, and the design system.
art-directionArt directionArt directed byDirection of the visual language and of commissioned work.
developmentBuildBuilt byImplementation, architecture, and performance of the build.
photographyPhotographyPhotographed byOriginal photography produced for the work.
illustrationIllustrationIllustrated byOriginal illustration or image-making produced for the work.
motionMotionAnimated byAnimation, motion design, and time-based sequences.
filmFilmFilmed byCinematography, editing, and moving image.
soundSoundScored byMusic, sound design, and audio production.
copyCopyWritten byCopywriting, editorial, and the words as published.
type-designTypeLettered byBespoke typeface or lettering drawn for the work.
strategyStrategyShaped byPositioning, naming, and the brief the work answers.
researchResearchResearched byUser research, testing, and the evidence behind decisions.
accessibilityAccessibilityAudited byAccessibility review, remediation, and assistive testing.
productionProductionProduced byScheduling, budget, and delivery of the work.
content-productionContentEdited byContent entry, migration, and editorial production.
infrastructureInfrastructureHosted byHosting, pipelines, and the operational surface.

Add what else is true of the site.

Six more fields are optional. A footer draws the creators, and the record page draws everything.

contributors
Everyone else who worked on the site. Listed on the record page and kept out of the footer.
materials
What the site was made with, such as a typeface, a library, a host or a palette.
licences
How the work itself is licensed, with a scope where the code and the writing differ.
awards
Recognition, with who gave it and when. It reads as a claim until it links to the issuer.
certifications
A conformance claim such as WCAG, with its assessor. One without an assessor is shown as self-declared.
measurements
A figure such as a Core Web Vital, with the tool that produced it and the date it was taken.

Check a record before you draw it.

validate returns every issue it finds. assertValid throws on the first error. An error means the credit must not be drawn. A warning means it draws and something is lost.

check.js

import { validate } from '@nodsto/record';

const { ok, issues } = validate({ ...record, statement: 'Made by {studio}' });

issues

[
  {
    "severity": "error",
    "code": "statement.slot.unknown",
    "path": "statement",
    "message": "Unknown slot {studio}. Known slots: {creators} {year} {title}."
  },
  {
    "severity": "warning",
    "code": "statement.noCreators",
    "path": "statement",
    "message": "The statement names nobody. Add {creators}, or leave it empty."
  }
]

Write the record into the page source.

The same record is written as JSON-LD for search engines and as humans.txt. Put the JSON-LD in a <script type="application/ld+json"> element.

build.js

import { toHumansTxt, toJsonLdString } from '@nodsto/record';

const jsonld = toJsonLdString(record, 2);
const humans = toHumansTxt(record);

jsonld

{
  "@context": "https://schema.org",
  "@type": "CreativeWork",
  "name": "Kiln",
  "url": "https://kiln.example",
  "datePublished": "2026",
  "author": [
    {
      "@type": "Organization",
      "name": "Marigold",
      "url": "https://marigold.example",
      "jobTitle": "Design"
    },
    {
      "@type": "Organization",
      "name": "Pocket Monday",
      "url": "https://pocketmonday.example",
      "jobTitle": "Build"
    }
  ],
  "material": [
    {
      "@type": "Thing",
      "name": "Five colours"
    }
  ]
}

humans.txt

/* TEAM */
  Design: Marigold
  Site: https://marigold.example

  Build: Pocket Monday
  Site: https://pocketmonday.example

/* SITE */
  Name: Kiln
  palette: Five colours

Publish the record as a page.

recordPage returns a whole HTML document with no script. It lists the creators and contributors, then the materials, licences, awards, certifications and measurements the record has. It takes canonical, siteName, theme and css.

Terminal

npm install @nodsto/page

build.js

import { recordPage } from '@nodsto/page';

const page = recordPage(record, { canonical: 'https://kiln.example/credits' });

With a record in hand, draw the credit.