---
title: "Add a Workshop"
description: "Turn a new business brief into a workshop listing and detail page."
canonical_url: "https://vercel.com/academy/build-and-launch-with-ai/add-a-workshop"
md_url: "https://vercel.com/academy/build-and-launch-with-ai/add-a-workshop.md"
docset_id: "vercel-academy"
doc_version: "1.0"
last_updated: "2026-09-25T16:42:54.189Z"
content_type: "lesson"
course: "build-and-launch-with-ai"
course_title: "Build and Launch with AI"
prerequisites:  []
---

<agent-instructions>
Vercel Academy — structured learning, not reference docs.
Lessons are sequenced.
Adapt commands to the human's actual environment (OS, package manager, shell, editor) — detect from project context or ask, don't assume.
The lesson shows one path; if the human's project diverges, adapt concepts to their setup.
Preserve the learning goal over literal steps.
Quizzes are pedagogical — engage, don't spoil.
Quiz answers are included for your reference.
</agent-instructions>

# Add a Workshop

# Add a workshop

The studio has a third workshop to list: a two-and-a-half-hour bookbinding session for $55. We'll add it through the same data that drives the existing cards and pages, then check that the inquiry reaches the owner with the right workshop name.

Start from the released production branch with a clean working tree. These commands assume it is named `main`:

```sh
git status
git switch main
git pull --ff-only
git switch -c add-bookbinding
```

Substitute your production branch if it has a different name. `--ff-only` updates the local branch only when Git can advance it without creating a merge. If it refuses, inspect the differing history before continuing.

## Outcome

Add bookbinding to the shared catalog and check that its page and inquiry email use the correct workshop details.

## Hands-on exercise 5.1

### Turn the brief into a record

The new workshop uses these fictional business details:

| Field         | Value                           |
| ------------- | ------------------------------- |
| Title         | Bind your own notebook          |
| Category      | Bookbinding                     |
| Duration      | 2.5 hours                       |
| Example price | $55, materials included         |
| Host          | Sam Okafor                      |
| Format        | In person at Small Hours Studio |
| Date          | Next date to be announced       |
| URL slug      | `bind-your-own-notebook`        |

The date remains unannounced. Keep that distinction visible so the site doesn't promise a scheduled session or available booking.

Start fx in the project folder with `/permissions ask`. Give it the brief and this request:

```text
Add the bookbinding workshop from this brief to the existing shared
workshop data. Use the slug bind-your-own-notebook. Keep the other
two workshops unchanged. Reuse the card, detail route, and inquiry
form so the new entry works through the existing components.
Write a short description and practical takeaways using the brief.
Use an existing accent style. Do not create a separate hard-coded
bookbinding page, add packages, or change email recipients.
Do not read secrets, commit, push, deploy, or send email.
```

Review the proposed data. A record may contain more fields than the visible card, including the detail description and takeaways. Check those fields too; the card can look complete while its detail page is missing information.

### Follow the record through the app

In the reference, `app/page.tsx` reads the `workshops` array and renders a card for every record. The detail route uses the same array for known paths and calls `getWorkshop` for the requested slug.

The interest validator also calls `getWorkshop`. Adding a valid record therefore makes its slug available to the inquiry flow. The email helper uses the corresponding title when constructing the subject.

Ask fx to point to each of those connections after making the edit. Check the files yourself. If it added a separate array of accepted form slugs, ask it to use the existing lookup so future catalog changes don't require updating two lists.

Use the editor to search for `bind-your-own-notebook`. In the reference, the business record lives in `lib/workshops.ts`; tests may also mention it. We shouldn't need a duplicate content record in the homepage or a new literal route folder.

### Review before testing

Exit fx and inspect the diff:

```sh
git diff --stat
git diff -- lib/workshops.ts
```

Substitute the data path used by your generated project. Verify both existing records still contain their original price and duration. Confirm the new slug is unique and the chosen accent is supported by the current styles.

Open the local catalog. It should display three cards. Follow the bookbinding link and reload its page directly. Compare the visible title, duration, and price with the brief.

## Try It

Review the new page at a narrow width. “Bind your own notebook” is longer than the other titles, so check the card's line wrapping and the space around its details link.

Make one local inquiry with your own reply-to address, keeping the configured recipient from Section 4. In the owner inbox, check that the subject reads “Workshop interest: Bind your own notebook” and the message body names the same workshop.

Run `npx tsx --test tests/course-interest.test.ts`, or the pnpm equivalent. Those existing tests check the shared form behavior; they should continue passing after the data addition.

### The card appears, but the page is missing

Compare the slug in the link with the new record, including spelling and hyphens. Check that the detail route's lookup and generated parameters read the same workshop collection. If the development server needs a restart after a route-related change, restart it and revisit the direct URL.

### The form rejects the new workshop

Inspect the validation lookup. It should use the shared catalog and recognize the new slug. A separate hard-coded list can become outdated. Check the submitted hidden field too; it must use the current detail page's record.

## Commit

Stage the reviewed data file and any test changes for the new workshop:

```sh
git add lib/workshops.ts
git diff --cached
git commit -m "feat(catalog): add the bookbinding workshop"
```

Keep the commit on `add-bookbinding`. We'll review a deployed version before proposing the release.

## Done-When

- [ ] Three cards appear, with the original two unchanged.
- [ ] Bookbinding opens directly at its own slug and survives reload.
- [ ] Its displayed facts match the brief at desktop and phone widths.
- [ ] A controlled inquiry identifies bookbinding and reaches the configured owner.

## Solution

Add this complete record to the `workshops` array in `lib/workshops.ts`, before its closing bracket:

```ts
  {
    slug: "bind-your-own-notebook",
    title: "Bind your own notebook",
    category: "Bookbinding",
    summary: "Fold, stitch, and give your next idea somewhere to land.",
    description: "Make a hand-bound notebook using a simple exposed stitch. We'll choose paper, fold signatures, and assemble a cover. No special equipment or perfect handwriting needed.",
    dateLabel: "Next date to be announced",
    duration: "2.5 hours",
    format: "In person · Small Hours Studio",
    price: "$55 · materials included",
    host: "Sam Okafor",
    takeaways: ["A hand-bound notebook", "A reusable stitching template", "The confidence to make another with everyday supplies"],
    accent: "lilac",
  },
```

Keep the comma separating this entry from the previous record. The reference app reads this record to build the card and detail page. Its inquiry lookup also uses the shared catalog, so it can recognize the new workshop. Review those results before saving the commit.


---

[Full course index](/academy/llms.txt) · [Sitemap](/academy/sitemap.md)
