Templates

PortalJS ships two starting points. Both are real Next.js projects with the same lightweight components/Table.tsx, Tailwind setup, and Next 14 config — they differ in whether they include the catalog and per-dataset showcase pages. /portaljs-new-portal picks the right one for your brief; you can also clone either by hand. For the surfaces these build — Home, Catalog, Showcase — see Core concepts.

The two templates

portaljs-catalog (default)portaljs-template
Pageshome + /search catalog + dataset showcasehome only
Dataset pagesone dynamic [owner]/[slug].tsx for allnone
Registrationdatasets.json manifestn/a
Adding a datasetone JSON entry + a data fileedit the home page directly
Best forany portal with a catalog of datasetsa single landing page

Default catalog — manifest-driven

examples/portaljs-catalog is the canonical template. Datasets are listed in a single datasets.json manifest; every entry is rendered by one dynamic pages/[owner]/[slug].tsx showcase route, served at /@<namespace>/<slug>. It ships three surfaces: a home page (/), a client-side search catalog at /search, and the per-dataset showcase. Adding a dataset is one JSON entry plus a data file — no new page:

{ "slug": "my-data", "name": "My Data", "description": "…", "file": "my-data.csv", "format": "csv", "namespace": "reference" }

Each entry carries a namespace. A portal uses one namespace mode for all datasets — theme (group by subject) or owner (group by publisher) — set via NAMESPACE_TYPE in lib/datasets.ts. It only changes the showcase's metadata label; the URL is always /@<namespace>/<slug>. See Core concepts for the rationale. /portaljs-add-dataset appends a manifest entry against this template.

Scaffold it with the CLI (recommended):

npm create portaljs@latest my-portal

Or grab the bare files with tiged (a maintained degit fork that reliably extracts a subdirectory):

npx tiged datopian/portaljs/examples/portaljs-catalog my-portal

Minimal variant — single page

examples/portaljs-template is a stripped-down starting point: just pages/index.tsx, _app, and _document — no catalog, no per-dataset pages. Use it when you want a single landing page and will add structure yourself, or as the smallest possible base to build on.

npx tiged datopian/portaljs/examples/portaljs-template my-portal

Which should I use?

  • Any portal with a catalog of datasets → the default catalog.
  • A single landing page you'll grow by hand → the minimal variant.
  • A live backend (CKAN, etc.) → start from the catalog, then run /portaljs-connect-ckan — it rewrites the showcase route to fetch from the backend.

The catalog static-exports cleanly (it pre-renders every manifest entry via getStaticPaths with fallback: false).

Where to go next