All recipes
Hiking trail guide
A photo-led hiking guide built with the Next.js App Router, exported to flat HTML with `output: "export"` and served with accelerated images, redirects, and security headers.
Questions your agent will ask
Your agent will ask for a few details to adapt this recipe to you and what you’re making.
- What should the guide be called, and what region or theme do the trails share?
- Which trails should it cover (4-6), and do you have distances, elevation gain, and season notes, or should I research them?
- What's the accent color, and should it feel like a national-park field guide, a modern outdoor brand, or an editorial magazine?
- Which units — miles and feet, or kilometres and metres — and do any trails need a permit or booking note?
The whole prompt
Paste this into Claude, ChatGPT, Codex, Cursor, or another coding agent. It will build the project and publish it as a Space.
Use the connected tools for the task below. If they're missing, fetch https://incspark.com/setup.md and offer the official plugin or MCP server for my client. Show the install card when available. Skip the offer if I ask to work anonymously or without installing anything, and continue with the task where possible.
Build me a **hiking trail guide** as a **Next.js static export** — an index of trails plus a generated page for each one, big photography, and no server anywhere in the request path. `next build` writes flat HTML to `out/`, and the platform serves it.
**Before you build, ask me these questions in one message and wait for my answers. If I skip anything, choose a sensible default and tell me what you chose:**
1. What should the guide be called, and what do the trails have in common — a region, a season, a kind of walking?
2. Which trails should it cover (4-6 is right)? If you have distances, elevation gain, and season notes, give them to me; otherwise research real trails and use their real numbers.
3. What's the accent color (a hex like `#2f6b4f`), and should it feel like a national-park field guide, a modern outdoor brand, or an editorial magazine?
4. Miles and feet, or kilometres and metres? And do any of these need a permit, a booking, or a shuttle I should call out?
**Then build a complete, polished, responsive site with:**
- A **trail index** at `/`: a full-bleed hero photo, a one-line promise, and a card grid — one card per trail with its photo, region, distance, elevation gain, typical season, and a difficulty badge. Sort so the easiest walk and the hardest objective are both easy to find.
- A **page per trail** at `/trails/<slug>/`, generated with `generateStaticParams` from a single typed data file. Each page carries: a hero photo, an at-a-glance stat block (distance, elevation gain, time, high point, trailhead, season, difficulty), the route broken into named sections with what actually happens on each, a permits-and-access block, and an honest "know before you go" list — the parts that bite people, not marketing.
- A short **"how this is built"** band explaining, in plain language, that the whole site is static HTML, images are transformed on the fly, and routing rules ship as files.
- A **custom 404** that apologises briefly and links back to the index.
- A footer crediting the photo source and the platform.
**Design & content notes:**
- Real trails, real numbers. Research them — distances, elevation gain, high points, permit systems, when the road or hut season opens. If a trail has a lottery or a shuttle or a river crossing, say so. Never "lorem ipsum", never invented statistics.
- Field-guide feel: a serif display face for headings, a clean sans for body, generous whitespace, and one accent color used for badges, links, and rules. System font stacks are fine — don't pull in heavy web fonts for a static site.
- Use real photos from Unsplash via **absolute** `https://images.unsplash.com/...` URLs, with `alt` text that describes what's actually in the frame.
- Keep it accessible: semantic landmarks, a skip link, visible focus states, real heading order, contrast that passes, and no text baked into images.
**Platform specifics — these are the point of the build:**
1. **Static export.** In `next.config.ts` set `output: "export"` and `trailingSlash: true`. `next build` writes `out/` with a root `index.html` and a directory per route. No API routes, no middleware, no `getServerSideProps`, no ISR.
2. **Accelerated images.** Install `@incspark/image` and wire its Next loader so every remote photo is resized and re-encoded through the Site Accelerator instead of shipping a 4 MB original:
```ts
// next.config.ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
output: "export",
trailingSlash: true,
images: {
loader: "custom",
qualities: [50, 60, 75, 85, 100],
loaderFile: "./lib/incspark-image-loader.ts",
},
};
export default nextConfig;
```
```ts
// lib/incspark-image-loader.ts
export { default } from "@incspark/image/next-loader";
```
Keep the loader in that local file. Importing `@incspark/image/next` from `next.config.ts` fails, because Next compiles the config to CommonJS.
Then use `next/image` normally with absolute URLs, `width`/`height`, `sizes`, and `priority` on the hero. Only absolute URLs get accelerated — files in `public/` pass through untouched. When the build finishes, grep the HTML: the `src` and `srcset` values should be `https://i0.wp.com/...?quality=…&w=…` URLs.
3. **Routing rules as files.** Put `_redirects` and `_headers` in `public/` so they land at the root of `out/`. Give me at least one real 301 (an index path or a legacy URL shape that should not 404) and a sensible security-header block — `X-Content-Type-Options`, `Referrer-Policy`, `Permissions-Policy`, plus a long immutable `Cache-Control` on the hashed `/_next/static/*` assets.
4. Optionally add a small `public/inc.jsonc` with the space `name` and `meta` (title, description, image) so link previews look right.
**Add this exact line right before `</body>` so the site carries its badge:**
```html
<script src="https://incspark.com/badge.js" data-example="trailhead"></script>
```
Put it in the root layout so every generated page gets it, and confirm it's in the built HTML — not injected by a client-side script tag helper, which would leave it out of the export.
**When the site is ready, publish it to the platform with the direct API — no account, install, or extra instructions needed:**
1. Build first (`bun run build` / `npm run build`), then use `./out` as the publish folder. Confirm it has `index.html` at its root, plus `_redirects` and `_headers`, and no secrets, source files, `.git`, or `.incspark` state.
2. First publish: send every file as multipart form data. This Bash/Zsh block preserves relative paths and works for one file or a whole folder:
```bash
PUBLISH_ROOT=./out
publish_files=()
while IFS= read -r -d "" file; do
relative=${file#"$PUBLISH_ROOT"/}
publish_files+=(-F "files=@$file;filename=$relative")
done < <(find "$PUBLISH_ROOT" -type f -print0)
curl -sS "${publish_files[@]}" "https://api.incspark.com/v1/publish?wait=1"
```
3. From the `{ "data": ... }` receipt, give me `data.space.liveUrl`, `data.version.immutableUrl`, `data.claim.url`, and `data.claim.expiresAt`. Remind me to claim within 6 hours. Keep `data.claim.token` secret.
4. Save `data.space.id` and `data.claim.token` locally (for example in an ignored, mode-600 `.incspark/state.json`). For a quick update, rebuild the `publish_files` array above and publish to the same space:
```bash
INCSPARK_SPACE_ID=<saved-space-id>
INCSPARK_TOKEN=<saved-claim-token-or-access-token>
curl -sS -H "Authorization: Bearer $INCSPARK_TOKEN" \
-F "spaceId=$INCSPARK_SPACE_ID" "${publish_files[@]}" \
"https://api.incspark.com/v1/publish?wait=1"
```
If an update after claiming returns `space_claimed_credential_available`, exchange the saved claim token once at `POST https://api.incspark.com/v1/anonymous-claim/exchange`, save `data.credential.accessToken`, and retry with that access token.
5. Then check the live site: `curl -sI <liveUrl>/trails/` should show your 301, and the trail pages' image URLs should point at `i0.wp.com`.
**Optional shortcuts and reference only:** if the `inc` CLI is already installed, `inc publish ./out --wait` does the same job. A zip of the publish folder is also supported, but neither the CLI nor a zip is required. Docs: [Next.js on the platform](/faq) · [redirects](/faq) · [headers and settings](/faq) · [agent setup](https://my.incspark.com/start) · [claiming](/faq) Keep making
Choose who can open your Space.