Skip to content
Back to skills

Website Dev

ASecurity

Ship changes to an existing Next.js (or static) site that auto-deploys from GitHub to Vercel, and prove they are live: fresh clone, canonical package manager and build, local production check, push or PR, poll Vercel's GitHub commit status for that exact SHA, then smoke-test the live page for expected content, not just HTTP 200. Covers the Vercel team-author deploy block, the stale `next start` trap, static bundles with no output directory, Supabase + Vercel production releases, and short cod...

  • 15 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 7, 2026
devopsgobashnextjsnodegitapisecurity

Works with

  • claude code
  • cli
  • api

Security analysis

A92/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 7 files and shows the line behind each finding

Scanned November 7, 2026

npx -y skills add jsath/claude-skills --skill website-dev --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Website Dev?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Website Dev
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/jsath-website-dev/badge)](https://www.skillsdirectory.com/skills/jsath-website-dev)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: website-dev
description: "Ship changes to an existing Next.js (or static) site that auto-deploys from GitHub to Vercel, and prove they are live: fresh clone, canonical package manager and build, local production check, push or PR, poll Vercel's GitHub commit status for that exact SHA, then smoke-test the live page for expected content, not just HTTP 200. Covers the Vercel team-author deploy block, the stale `next start` trap, static bundles with no output directory, Supabase + Vercel production releases, and short coding-agent briefs. Use when asked to build, fix, add a page to, deploy, redeploy or verify a website, or when a Vercel deploy did not happen. Requires Claude Code with git and an authenticated gh CLI."
---

# Website Dev: build, push, prove it is live

A push is not a deploy and a 200 is not the right page. This skill ends only when the
exact commit is deployed and the live page shows the expected content.

## Inputs

- GitHub repo (`owner/repo`) and the branch to ship to (default branch or a PR branch).
- The change, and one **identity string**: a title or sentence that only the new version contains.
- Live URL of the route (production domain or preview URL).

Missing the identity string? Pick one from the change itself (new heading, new title) before you start.

## Rules

- Work in the existing repo and the existing Vercel project. Never create a new Vercel project for a site that has one: one repo, one project, one URL.
- Never force-push, rewrite history, or push a build that fails. Never commit `.env*`, keys or tokens; never print secret values.
- The commit author must be a GitHub account that belongs to the Vercel team, or Vercel blocks the deploy (see step 6).
- Use the package manager the repo declares (`packageManager` field + its lockfile). A green build from the wrong one does not count.

## Steps

### 1. Fresh clone and preflight
```bash
gh repo clone <owner/repo> ~/tmp/<repo> && cd ~/tmp/<repo>
git remote show origin | grep 'HEAD branch'          # main vs master
gh auth status                                        # which account will author
git config user.name "<vercel-team member>"; git config user.email "<their GitHub noreply email>"
```
If you already have a working tree with uncommitted relevant work, continue that instead of overwriting it.

### 2. Install
`pnpm install --frozen-lockfile` / `npm ci` / `yarn --frozen-lockfile` / `bun install` to match the lockfile.
On npm peer-dependency conflicts: `npm install --legacy-peer-deps`. Then `git diff package-lock.json`: revert lockfile noise you did not intend (a renamed clone dir can rewrite the `name` field).

### 3. Change, then build
Make the change. Run the canonical build (`pnpm run build` etc.). Fix every error, rerun. After any later edit, rerun the build; an earlier green build is stale.
For a new Next.js route, confirm it appears in the build's route table and add it to `app/sitemap.ts` (or the sitemap source) and any index/nav page that lists siblings.

### 4. Local production check
```bash
lsof -nP -iTCP:3100 -sTCP:LISTEN            # anything here? if it is YOUR old next start, kill that PID (the node child, not just the npm wrapper)
PORT=3100 npm run start &
curl -s localhost:3100/<route> | grep -c "<identity string>"   # must be >= 1
```
An old `next start` whose `.next` folder was replaced returns 200 with blank or stale content. If the page renders client-side only, check the route's JS chunk or use a headless browser; view the page at 390 px and 1440 px wide for clipping and overflow.

### 5. Push
- Default branch: `git push origin HEAD`. PR flow: `git push -u origin <branch>` then `gh pr create`.
- Record `SHA=$(git rev-parse HEAD)`.

### 6. Prove the deploy
```bash
scripts/verify-deploy.sh <owner/repo> $SHA https://<domain>/<route> "<identity string>" 600
```
It polls Vercel's **legacy commit status** (Vercel reports there even when Checks and Deployments look empty), then fetches the live URL until the identity string appears.

| exit | meaning | do this |
|---|---|---|
| 0 | deployed, content verified | report done |
| 1 | Vercel failure/error | open the printed target_url, quote the exact error, fix, push a new commit |
| 2 | timed out while pending/building | keep polling once more; if still pending, report the target_url |
| 3 | deployed but content missing | catch-all route returning a fallback, wrong URL, CDN cache, or client-only render; verify the JS chunk |
| 4 | no Vercel status at all | Git integration, ignored build step, branch settings, or author gate; see below |

**Author gate** (status says the author is not a team member, or links to a team invite): push an empty commit authored by a team member on the same branch: `git commit --allow-empty -m "chore: trigger vercel deployment" && git push`, then rerun step 6 on the new SHA. For a PR preview, do it on the PR branch, not main. A squash merge can keep the PR author as commit author even when a team member merged it: check `gh api repos/<o>/<r>/commits/<sha> --jq .author.login`. Full diagnosis: `references/vercel-author-gate.md`.

## Specialised paths

- Static/custom bundle fails with `No Output Directory named "public" found`: `references/vercel-static-output.md`.
- Next.js + existing hosted Supabase going to production (migrations, RLS, Auth/SMTP, env vars, first admin user): `references/supabase-vercel-release.md`. Never `supabase db reset` against production.
- Read-only audit of a site repo (routes, sitemap drift, downloads, leaked credentials, build readiness): `references/read-only-site-audit.md`.
- Writing a prompt for another coding agent (Codex, a subagent): `templates/coding-agent-brief.md`. Keep it 300-700 words; if the user says it is too long, cut it by half, do not defend it.

## Progress reporting (long jobs)

Report against gates, not vibes: 1 code changed, 2 build passed, 3 local check passed, 4 visual QA done, 5 pushed (SHA), 6 Vercel success, 7 live content verified. Anything short of 7 is "not deployed yet", said plainly.

## Output format

```text
Shipped: add /pricing FAQ section
Repo: acme/site  branch: main  SHA: 3f9c2e1
Build: pnpm run build, passed (route /pricing in table)
Local: /pricing 200, "Frequently asked" present; 390px + 1440px checked
Vercel: success, https://vercel.com/acme/site/8kq...
Live: https://www.acme.com/pricing 200, "Frequently asked" present
Open: none
```

## Failure handling

- `gh` not authenticated: stop and ask the user to run `gh auth login`; do not paste tokens into chat.
- Build fails on untouched code: report it as pre-existing with the error, do not push.
- Vercel CLI says the token is not authorised for the scope: the GitHub side is done; the blocker is Vercel team/token scope. Say so.
- Production points at a different SHA than yours: state it and investigate before claiming success.

## Security check before every push

`git diff --cached | grep -nE '(sk-|ghp_|xox[bp]-|AKIA|BEGIN .*PRIVATE KEY|SUPABASE_SERVICE_ROLE|=.{32,})'` must be empty, `.env*` must be gitignored, and no secret may carry a `NEXT_PUBLIC_` prefix.

Files in this skill

  • SKILL.md6.9 KB
  • references/read-only-site-audit.md5.1 KB
  • references/supabase-vercel-release.md10.1 KB
  • references/vercel-author-gate.md3.3 KB
  • references/vercel-static-output.md2.5 KB
  • scripts/verify-deploy.sh2.3 KB
  • templates/coding-agent-brief.md1.9 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.