Langfuse-docs customer-story-setup
git clone https://github.com/langfuse/langfuse-docs
T=$(mktemp -d) && git clone --depth=1 https://github.com/langfuse/langfuse-docs "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.agents/skills/customer-story-setup" ~/.claude/skills/langfuse-langfuse-docs-customer-story-setup && rm -rf "$T"
.agents/skills/customer-story-setup/SKILL.mdSingle source of truth: maintain this skill under
only. Claude and Cursor load projected copies under.agents/skills/customer-story-setup/and.claude/skills/customer-story-setup..cursor/skills/customer-story-setup
Customer story setup (MD -> MDX)
Turns a plain Markdown draft into
in the
same pattern as content/customers/<slug>.mdx
content/customers/canva.mdx and cresta.mdx.
Before writing any file: collect missing input
Do not guess. If any item below is missing from the user's draft or message, ask explicitly and wait for answers (or confirm defaults).
Content & publishing
| Topic | Ask |
|---|---|
| Company name | Legal/marketing name for copy and quotes |
| Company website | Public URL for the link in About <Company> |
| Slug | Filename: (lowercase, hyphens), e.g. -> |
| Page title | H1 string for + YAML (often "How <Company> ... with Langfuse") |
| Short description | YAML + description (SEO/social; 1-2 sentences) |
| Publish date | YAML + (e.g. ) |
| OG image | Optional path; if unset, leave empty like other stories |
Authors (BlogHeader authors={["..."]}
)
authors={["..."]}| Topic | Ask |
|---|---|
| Byline author(s) | Who should appear under the title (keys from ) |
| External / guest speaker | If not in : collect name, title, optional socials, and headshot path under or , then add an entry to (see existing entries). Every key must resolve in . |
Branding & Users index card
| Topic | Ask |
|---|---|
| Logos | Paths for and (light + dark mode), usually under |
| Pull quote | (short, for grid card) |
| Quote attribution | , , |
| Speaker headshot (optional) | for card/SEO if you use the same as Canva |
| Show on /users | `showInCustomerIndex: true |
Images (screenshots & diagrams)
Produce a numbered checklist for the user (and keep it in the PR description if useful):
- Folder:
public/images/customers/<slug>/ - For each asset: filename, purpose, where it appears (section + suggested alt text)
- Remind: customer posts use
around markdown images, e.g.<Frame fullWidth>
per site conventions - Size each image by aspect ratio (run
to get dimensions):sips -g pixelWidth -g pixelHeight <file>- Portrait / square (ratio <= 1:1) ->
<div className="flex justify-center"><Frame fullWidth className="w-1/2">...</Frame></div> - Landscape (~1.5:1) ->
<div className="flex justify-center"><Frame fullWidth className="w-2/3">...</Frame></div> - Panoramic (> 2:1) ->
(no centering wrapper needed)<Frame fullWidth className="w-full">...</Frame>
- Portrait / square (ratio <= 1:1) ->
If the draft says "screenshot here" without files, list placeholders in MDX with consistent paths so the user can drop files in later.
Docs links (optional but recommended)
Ask whether to add sparse internal links. Default policy: only link major product concepts (match what we used on Cresta):
- Observability overview
- Prompt management and/or Playground
- Scores
- Self-hosting
- OpenTelemetry
- Experiments
- LLM-as-a-judge
- Prompt version control
Do not pepper every noun with links. Use paths from
/
available-internal-links rule so links resolve.llms-docs.txt
MDX structure to produce
- YAML frontmatter at top:
,title
,date
,description
,ogImage
,tag: customer-story
(display string if needed),author
,customerLogo
, optional quote fields,customerLogoDark
.showInCustomerIndex - Imports:
,BlogHeader
(if quote),CustomerQuote
(if impact section),ImpactChart
; useCustomerStoryCTA
for images (global in MDX).Frame
:BlogHeader
,title
,description
,customerLogo
,authors
; optionaldate
for hero.image- Body headings: One conceptual H1 only (from
). Body usesBlogHeader
and##
; do not skip levels.### - Quote block:
<CustomerQuote quote="..." name="..." role="..." company="..." />- align
/role
with frontmatter so the byline reads "Name, Role at Company"company - avoid duplicating company name in
role
- align
- Images: size by aspect ratio (see checklist item 4 under Images above)
- portrait/square ->
centeredw-1/2 - landscape ->
centeredw-2/3 - panoramic ->
w-full
- portrait/square ->
- Closing:
(optional) then<ImpactChart items={[{ area, impact }, ...]} />
.<CustomerStoryCTA />
Reference implementations:
content/customers/canva.mdx,
content/customers/cresta.mdx.
Repo wiring (after MDX exists)
-
content/customers/meta.json- Add
to the"<slug>"
array (withpages
first)."index" - Order matters for layout: the Users grid and homepage carousel are
sorted by
insortCustomerStoriesByMetaOrder
, which reads this list. Place the slug where the card should appear (e.g. last in the list = bottom-right in a 2-column grid).lib/sortCustomerStoriesByMeta.ts
- Add
-
Authors
- If new author: add to
(key must matchdata/authors.jsonBlogHeader
).authors
- If new author: add to
-
Assets
- Logos and story images under
.public/images/customers/<slug>/
- Logos and story images under
Checklist before finishing
- All required fields collected from user (or documented as TBD)
-
keys exist inauthorsdata/authors.json -
includes slug in desired ordermeta.json - Image checklist given to user with folder path
- Company website link in About section
- Docs links only where agreed; no broken internal URLs
- Replace all em dashes with regular hyphens (
) - the linter will do this anyway; better to do it upfront- - Follow
/AGENTS.md
: one H1 via BlogHeader, American English, accessible alt textdocumentation-pages.mdc
Quick YAML skeleton (adapt fields)
--- title: "..." date: ... description: ... ogImage: tag: customer-story author: ... customerLogo: "/images/customers/<slug>/...-light.png" customerLogoDark: "/images/customers/<slug>/...-dark.png" customerQuote: "..." quoteAuthor: "..." quoteRole: "..." quoteCompany: "..." showInCustomerIndex: true ---