Turning a book appendix into a prompt library
260 insurance prompts were stuck inside a Kindle book. A 60-line script and two Next.js routes made them a free, searchable library on FixMyPrompt.

I published a Kindle book for insurance agents this month. The appendix has 260 prompts in it, sorted into 20 jobs an agent does every week: renewal calls, claims follow-ups, cross-sell emails, and so on. I spent more time on that appendix than on most of the chapters.
Then it sat inside a book, where nobody can copy and paste from it.
After a week of that bugging me I turned it into a page on FixMyPrompt. Here's how little work that took, and the one thing I got wrong.
The source was already structured
The appendix lives in my repo as a single markdown file. Each section is a heading with the category name and a numbered list of prompts under it. That's close enough to data that I didn't want to retype it or hand-maintain a JSON copy that would drift from the book.
So step one was a 60-line script that reads the markdown, splits on headings, pulls out the numbered items, and writes a TypeScript file:
export interface TemplatePrompt { n: number; text: string }
export const INSURANCE_PROMPTS: Record<string, TemplatePrompt[]> = {
"renewal-calls": [ { n: 1, text: "..." }, ... ],
...
};
The key is the slug for each category. Twenty keys, 260 prompts, all generated. When I revise the appendix for a second edition I rerun the script and the site picks it up.
A second file, written by hand, holds the per-category copy: title, H1, meta description, a short intro, and which scoring goal the category maps to when a prompt gets sent to the grader. I kept that file small on purpose because it's the only part I want to touch manually.
Static pages from a data file
FixMyPrompt is a Next.js App Router site. The library is two routes: an index at /templates/insurance and a dynamic [category] route under it.
The category route runs generateStaticParams over the 20 slugs with dynamicParams = false, so every page builds at deploy time and any slug not in the list returns a 404 instead of an empty shell. Each page gets ItemList JSON-LD, a canonical URL, a breadcrumb, and a related-categories block that picks the two neighbors on either side in the ordered list.
Each prompt is a card with two buttons. Copy puts the text on the clipboard. The second button is the reason I built the page.
Prefilling the grader from a URL
The main tool on FixMyPrompt is /try: paste a prompt, get a score out of 100 and a rewrite. The template cards link into it like this:
/try?prompt=<encoded text>&goal=quality&src=tpl-renewal-calls
On the /try side a small client component reads useSearchParams, checks goal against the allowed values, caps the prompt at 4000 characters, and sets the form state once on mount. It sits inside <Suspense> so the page itself stays static. The src param goes into an analytics event so I can see which categories send people through to a report.
That's the whole integration. The template pages know one URL shape and nothing else about the grader.
What I got wrong
My first pass at the per-category intro copy mentioned things like binding restrictions and ACA subsidies. Sounded right for an insurance audience. None of it was in the appendix. I had written descriptions of prompts that didn't exist.
I caught it by reading every section of the source against every intro, and ended up rewriting 13 of the 20 strings. If you generate site copy from a source document, check the copy against the source and not against what the topic feels like it should say.
Where it landed
Twenty-one new URLs in the sitemap, a free resource that didn't exist the day before, and a path from a book page to a working tool. The book is AI for Insurance Agents if you want to see where the prompts came from. The library is at fixmyprompt.net/templates/insurance.
Adding another industry is one data file and one category file. That was the goal going in and it held up.
Comments
No comments yet. Be the first.