Skip to content

Product Registration

Before documentation can be deployed via the Upload API, a product must be registered. Products can be managed through the Admin UI, the API, or by placing JSON config files in the config directory.

The easiest way to register products is through the Admin UI at /admin/:

  1. Sign in with your email (one-time code)
  2. Navigate to the product management section
  3. Click "Create Product"
  4. Fill in the product details (name, display name, description, visibility)
  5. Save

See Admin UI for the full workflow.

API

Products can be created, updated, and deleted via the API. All mutating endpoints require authentication.

Create a Product

bash
curl -X POST \
  -H "Authorization: Bearer $SHELF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "configuration",
    "displayName": "Cocoar.Configuration",
    "description": "Reactive configuration for .NET",
    "source": "upload",
    "visibility": "public",
    "tags": ["C#", ".NET"],
    "showWhenEmpty": false
  }' \
  https://docs.cocoar.dev/_api/products

Update a Product

bash
curl -X PUT \
  -H "Authorization: Bearer $SHELF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "displayName": "Cocoar.Configuration",
    "description": "Updated description",
    "visibility": "preview",
    "tags": ["C#", ".NET", "Configuration"],
    "showWhenEmpty": true
  }' \
  https://docs.cocoar.dev/_api/products/configuration

Delete a Product

bash
# Remove registration only (docs files kept on disk)
curl -X DELETE \
  -H "Authorization: Bearer $SHELF_API_KEY" \
  https://docs.cocoar.dev/_api/products/configuration

# Remove registration AND all documentation files
curl -X DELETE \
  -H "Authorization: Bearer $SHELF_API_KEY" \
  "https://docs.cocoar.dev/_api/products/configuration?deleteData=true"

JSON Config Files

Products can also be registered by placing JSON config files in {ConfigRoot}/products/, one file per product:

/data/config/
└── products/
    ├── configuration.json
    ├── capabilities.json
    └── filesystem.json

Config File Format

Each JSON file describes one product:

json
{
  "name": "configuration",
  "displayName": "Cocoar.Configuration",
  "description": "Reactive configuration for .NET",
  "source": "upload",
  "visibility": "public",
  "tags": ["C#", ".NET"],
  "showWhenEmpty": false
}
FieldRequiredDescription
nameYesProduct identifier, used in URLs and API calls
displayNameNoHuman-readable name for API responses and landing page
descriptionNoShort description of the product
sourceNoDeployment source type. Default: "upload"
visibilityNo"public" or "preview". Default: "public"
opennessNo"OpenSource", "Proprietary" or "Unspecified". Drives a badge + filter on the landing page (display-only). Default: "Unspecified"
repositoryUrlNoOptional source-repository link; when set, the landing card shows a "Source ↗" link
tagsNoList of free-form labels (e.g. ["C#", "UI"]). Used for filtering on the landing page
showWhenEmptyNoShow on landing page even without any deployed versions. Default: false

TIP

The name field determines the URL path, not the filename. By convention, keep both in sync (e.g., configuration.json with "name": "configuration").

Visibility

The visibility field controls how a product appears on the landing page:

ValueBehavior
"public"Shown on the landing page by default (if it has stable versions, or showWhenEmpty is set)
"preview"Hidden by default, shown when "Show preview" is toggled on

Preview visibility is useful for products that are in development or not yet ready for general use. The documentation is still accessible via direct URL regardless of visibility.

Tags

Tags are free-form labels you can attach to a product (e.g. "C#", "UI", ".NET", "CLI"). They appear as chips on product cards, and the landing page provides a tag filter bar so visitors can narrow down the list to products that interest them.

Tags are stored as an array of strings. Shelf normalises them automatically: leading/trailing whitespace is trimmed, duplicates and empty values are removed, and the list is sorted alphabetically.

json
{
  "tags": ["C#", ".NET", "Configuration"]
}

The openness field marks whether a product's source is public — "OpenSource", "Proprietary", or "Unspecified" (the default). Marked products get a colored badge on the landing page and can be filtered by it, so open-source and proprietary documentation can be hosted side by side and told apart at a glance. It is a display marker only — it does not restrict access. To actually hide a product, mark it restricted instead.

Set repositoryUrl to show a discreet "Source ↗" link on the product card — typically for open-source products. Leave it empty and the card carries no repository link, which is the usual choice for proprietary products.

json
{
  "openness": "OpenSource",
  "repositoryUrl": "https://github.com/cocoar-dev/configuration"
}

Show When Empty

By default, a product only appears on the landing page once it has at least one deployed version. Set showWhenEmpty: true to display the product card immediately — even before any documentation is uploaded. The card is rendered in a distinct teaser style with a "Coming soon" indicator.

This is useful for:

  • Testing — verify the product is registered and visible before pushing the first version
  • Teasers — announce upcoming documentation while it is still being written
json
{
  "showWhenEmpty": true
}

Live Reload

Config files are loaded at startup and monitored for changes. When you add, modify, or remove a config file, Shelf picks up the change automatically -- no restart needed.

Why Registration?

Product registration is required for the Upload API to prevent accidental creation of arbitrary products. Without registration, a typo in a CI pipeline (configration instead of configuration) would silently create a new product.

Manual deployment (copying files directly into the docs volume) does not require registration -- Shelf serves any product directory it finds, regardless of whether a config file exists.

API Integration

Registered products are visible via the API:

bash
# List all registered products with their versions
curl https://docs.cocoar.dev/_api/products
json
[
  {
    "name": "configuration",
    "displayName": "Cocoar.Configuration",
    "description": "Reactive configuration for .NET",
    "source": "upload",
    "visibility": "public",
    "tags": ["C#", ".NET"],
    "showWhenEmpty": false,
    "latest": "v5",
    "versions": ["v5", "v4"]
  }
]

Shelf your Docs.