CREATE
Reusable Technical Deliverables Scripts
CORE.
I realized relatively quickly that I was asking AI agents to do the same thing over and over again. Simple requests like create this page in the same way or create this component with the same specifications. This is a very very inefficient and costly way to use AI.
WHAT'S THE SOLUTION
Creating new pages
Most if not all unppps in the unparty.app contain reusable scripts to create technical deliverables without having to touch code.
In theunpartyapp, a Next.js application, you will find create-page.
Scripts
create-page - Single Page Creation
Creates one project page from an editorial article you already have (make one with ./create-article first). On Windows, run it from Git Bash.
Usage:
./create-pageIt asks for two things:
Page name: lowercase words joined by dashes (my-project). It becomes the directory src/app/{page-name}/ and the address /{page-name}. Refused if the directory already exists or the name starts with theunparty (reserved for unparty's own pages)
Article: the article's export name in capitals (MY_FIRST_ARTICLE). Refused unless it is imported in src/app/constants/editorial-articles/registry.ts
Then it:
Writes src/app/{page-name}/page.tsx (see Generated Page Structure)
Adds '/{page-name}' to STATIC_ROUTES in src/lib/site-routes.ts, so the page is in /sitemap.xml (only /theunparty* folders are discovered automatically)
Example:
$ ./create-page
Page name (lowercase words joined by dashes, e.g. my-project): my-project
Article to show (its name in capitals, e.g. MY_FIRST_ARTICLE): MY_FIRST_ARTICLE
Created: src/app/my-project/page.tsx
Sitemap: added /my-project to src/lib/site-routes.tsThe step-by-step version for site owners is Your first project page.
Generated Page Structure
create-page writes a server component that takes everything from the article: title, description and category for the metadata, the cover (from the article's coverImage) for the hero and link preview, and published as a draft gate:
import type { Metadata } from 'next';
import { notFound } from 'next/navigation';
import { generatePageMetadata } from '@/app/utils/ogMetadata';
import UnpppPageShell from '../components/UnpppPageShell';
import EditorialArticle from '../components/editorial/EditorialArticle';
import { MY_FIRST_ARTICLE } from '../constants/editorial-articles/articles/my-first-article';
export const metadata: Metadata = generatePageMetadata({
title: MY_FIRST_ARTICLE.title,
description: MY_FIRST_ARTICLE.description,
category: MY_FIRST_ARTICLE.category,
coverId: MY_FIRST_ARTICLE.coverImage?.match(/^\/covers\/([^/.]+)\./)?.[1],
path: '/my-project',
});
export default function MyProjectPage() {
// Same rule as /article/<slug>: a draft (published: false) is never public
if (!MY_FIRST_ARTICLE.published) notFound();
return (
<UnpppPageShell>
<EditorialArticle article={MY_FIRST_ARTICLE} />
</UnpppPageShell>
);
}unparty's own /theunparty* pages add AboutComponent (effort chart, repo stats, onboarding steps) below the article. It reads src/data/UnpppsConfig.json, so it only belongs on pages that have an entry there.
Next Steps After Page Creation
1. Type-check: npx tsc --noEmit (no output means it is fine)
2. Look at it: npm run dev, then open /{page-name} at phone width and desktop
3. Publish: commit page.tsx and site-routes.ts, then push
Requirements
Node.js: For running the Next.js application
Bash: macOS and Linux have it; on Windows, use Git Bash
Troubleshooting
Script not executable:
chmod +x create-pagePage already exists:
create-page refuses a name whose directory already exists
Delete the existing directory if you want to recreate it