| name | portaljs-deploy |
| description | Deploy a PortalJS portal to PortalJS Arc — Datopian-managed static hosting on Cloudflare. Builds a static export, uploads it, and returns a live SLUG.arc.portaljs.com URL. One command, one target. Use when a portal is ready to publish or redeploy to a live URL. |
| allowed-tools | Read, Write, Edit, Bash(npm:*), Bash(npx:*), Bash(curl:*) |
| version | 1.0.0 |
| author | Datopian <hello@datopian.com> |
| license | MIT |
| compatibility | Claude Code with PortalJS portals (Next.js 14, React 18, Node 18+). Runs from any project via the plugin, a personal ~/.claude/commands install, or a portaljs clone. |
| tags | ["portaljs","data-portal","deploy","hosting","cloudflare","static"] |
PortalJS — Deploy
Overview
Publish an existing PortalJS portal to PortalJS Arc — Datopian's managed static
hosting on Cloudflare. Build a static export, upload it to the Arc API, and print a live
https://SLUG.arc.portaljs.com URL. Re-running redeploys the same portal (idempotent on
the slug). This is a single-target skill — it deploys to Arc only. For self-hosting, run
npm run build and upload out/ to any static host; no skill required for that path.
Arc serves static exports only — SSR is not hosted on Arc yet.
Prerequisites
- A PortalJS portal directory with a
package.json that lists next as a dependency.
- Node 18+ and npm on PATH (the Arc device-login flow uses Node's global
fetch).
curl and tar available for packaging and upload.
- A PortalJS Arc token — read from
PORTALJS_TOKEN, or ~/.portaljs/credentials
({"token":"…"}). If neither exists, the skill signs in on demand via a device-code
flow; no manual token copying required.
- If the portal stores large data in Git LFS/R2, do not run
git lfs pull before
deploying — large datasets are served from Cloudflare R2 via absolute URLs in
datasets.json, not copied into the export.
Instructions
The canonical, full step-by-step workflow is
.claude/commands/portaljs-deploy.md — the
single source of truth. Read and follow it when executing. Summary:
- Gather input — portal directory (default
.) and slug (default from package.json
name or directory name, slugified). Confirm the directory is a Next.js project; reject
reserved slugs (www, api, admin, staging, arc).
- Resolve the Arc token: read
PORTALJS_TOKEN, else ~/.portaljs/credentials; if
missing, run the device-authorization sign-in flow and save the returned token.
- Ensure
next.config.js sets output: 'export' and images: { unoptimized: true },
then run npm run build; stop if the build fails.
- Verify the export carries no dataset bytes — run (or
) to catch Git LFS pointer leaks and oversized data files.