- Click the button above (or go to repo → Code → Codespaces → Create codespace on main)
- Wait ~2-3 minutes for the environment to set up
- Run the dev server:
pnpm dev
- A preview window will automatically open
- Edit files in
content/posts/and see live changes! - Commit and push when done
Free Tier Limits:
- GitHub Free: 120 core-hours/month (~60 hrs on 2-core machine)
- GitHub Pro: 180 core-hours/month (~90 hrs on 2-core machine)
- Auto-stops after 30 min idle (just close the tab when done!)
- Check usage: github.com/settings/billing
pnpm install
pnpm devVisit http://localhost:3000
- Open
/admin(it redirects to Keystatic's required/keystaticroute). - Open Posts and choose Create post.
- Enter the title first. It becomes the post slug and its image-folder name.
- Choose or drop a featured image into Featured image.
- In Content, use the image toolbar button, paste an image, or drag and drop it into the editor.
- Add useful alt text, preview the post, and save.
New images are committed with the post and organized automatically:
content/posts/my-new-post.md
public/uploads/my-new-post/cover.jpg
public/uploads/my-new-post/diagram-one.png
Existing posts keep their legacy /uploads/YYYY/MM/... image paths. The Existing featured image path (legacy) field is only for those posts; leave it empty when creating a new post.
For local authoring, run pnpm dev and visit http://localhost:3000/admin.
Keystatic writes Markdown and images back to GitHub through server-side API routes. A static Cloudflare Pages export cannot run the admin API, so the hosted editor is deployed as a full-stack Next.js Worker through OpenNext. Set:
NEXT_PUBLIC_KEYSTATIC_STORAGE_KIND=githubNEXT_OUTPUT_MODE=serverKEYSTATIC_GITHUB_CLIENT_ID=...KEYSTATIC_GITHUB_CLIENT_SECRET=...KEYSTATIC_SECRET=...NEXT_PUBLIC_KEYSTATIC_GITHUB_APP_SLUG=...Before the GitHub App exists, start Keystatic's one-time setup mode with
NEXT_PUBLIC_KEYSTATIC_STORAGE_KIND=github pnpm dev, then open
http://127.0.0.1:3000/keystatic/setup.
The storage-mode flag is public because both the browser UI and server route
must select GitHub storage; it contains no credential or secret.
Copy .env.example as a checklist. The GitHub App values can be generated from Keystatic's setup screen. Give the app access only to PreferredAI/PreferredAI.github.io; authors must have repository write access. A repository administrator can normally install Keystatic's repository-scoped app unless the organization has restricted installations to owners.
Run pnpm build:worker to produce the Cloudflare-compatible server build and pnpm preview:worker to test it locally. Keystatic requires server-side routes; a static export cannot provide its API or GitHub OAuth callbacks.
The test-keystatic branch deploys to the separate preferredai-keystatic Worker through .github/workflows/deploy-keystatic-test.yml. This leaves the existing Pages deployment and preferred.ai unchanged during testing.
The test workflow uses a separate CLOUDFLARE_WORKERS_API_TOKEN Actions secret. Do not replace the existing CLOUDFLARE_API_TOKEN, which remains scoped to the production Pages workflow.
Do not merge the Worker deployment into the production workflow or move the custom domain until the temporary Worker passes a complete GitHub login, edit, image upload, save, and rebuild test.
- Open the project in Codespaces (see above)
- Create a new file in
content/posts/namedyour-post-title.md - Copy content from
.github/BLOG_POST_TEMPLATE.md - Edit your post and preview live at port 3000
- Commit and push
- Copy content from
.github/BLOG_POST_TEMPLATE.md - Go to
content/posts/on GitHub - Click "Add file" → "Create new file"
- Name it:
your-post-title.md(lowercase, hyphens) - Paste the content from
.github/BLOG_POST_TEMPLATE.md. Frontmatter should look like this:--- title: "Your Post Title"date: "2025-12-02"# YYYY-MM-DDauthor: "Your Name"excerpt: "Brief summary (1-2 sentences)"featuredImage: "/uploads/2025/12/image.jpg"categories: ["Education"] # "Presentation, "Travel, "Education", "Announcement", "Video", "Defense", "Publication", "Social"tags: []seoTitle: "Your Post Title - Preferred.AI"seoDescription: "Brief summary for SEO" ---
- Write your content in Markdown. Upload images to
public/uploads/YYYY/MM/first if needed. (The Admin UI above handles this automatically for new posts.) - Commit to a new branch and create a Pull Request
Clone the repository:
git clone https://github.com/PreferredAI/PreferredAI.github.io.git cd PreferredAI.github.ioInstall dependencies:
pnpm install
Create a new Markdown file in
content/posts/using the template from.github/BLOG_POST_TEMPLATE.md.Start the development server:
pnpm dev
Open http://localhost:3000 to preview your post.
Once satisfied, commit your changes to a new branch and push to GitHub. Create a Pull Request for review if needed.
- Edit name, image (path), title, link in
src/data/team.tsx - Upload corresponding images to
public/uploads/YYYY/MM/
- Edit photo details (path, date, location) in
src/data/teamPhotos.ts - Upload corresponding images to
public/team/