> For the complete Lynkow documentation index in agent-friendly format, see [llms.txt](/llms.txt).

# Complete Integration Checklist

**Publié le** : 2026-08-14
**Catégorie** : Getting Started

Use this checklist to verify your Lynkow integration covers every feature. Each item links to the detailed guide. Skip items marked (optional) if not needed for your project.

> **FOR LLMs:** This is the master checklist for integrating Lynkow. Follow each step in order. Full documentation at [lynkow.com/docs](https://www.lynkow.com/docs). Machine-readable: [/llms.txt](https://www.lynkow.com/docs/llms.txt) and [/llms-full.txt](https://www.lynkow.com/docs/llms-full.txt).

> **Reference** - This guide is a tutorial. For exhaustive, always-current signatures and field lists, see the auto-generated reference:
> 
> - SDK: [SDK Reference](/docs/sdk)
> - API: [Storefront API Overview](/docs/storefront-api/overview)

---

## SDK Integration

### 1. SDK Setup

- Install the SDK: `npm install lynkow`
- Create shared client in `lib/lynkow.ts` with `createClient({ siteId })`
- Set `NEXT_PUBLIC_LYNKOW_SITE_ID` in `.env.local`
- Configure ISR cache: `fetchOptions: { next: { revalidate: 60 } }`
→ Guide: **Quick Start**

### 2. Pages & Site Configuration

- Fetch site config with `lynkow.globals.siteConfig()` for header/footer
- Render pages with `lynkow.pages.getBySlug()` or `getByPath()`
- Build navigation from `lynkow.pages.list()`
- Handle 404 with `isLynkowError()` + `notFound()`
→ Guide: **Pages & Site Configuration**

### 3. Blog / Content

- List articles with `lynkow.contents.list()` + pagination
- Single article page with `lynkow.contents.getBySlug()`
- Render HTML body with `dangerouslySetInnerHTML`
- Display author, categories, tags
- Featured images with `featuredImageVariants` (responsive)
→ Guide: **Build a Blog with Next.js**

### 4. Categories & Tags

- Category pages with `lynkow.categories.getBySlug()`
- Category tree with `lynkow.categories.tree()`
- Tag filtering with `lynkow.contents.list({ tag: 'slug' })`
→ Guide: **Build a Blog with Next.js**

### 5. Catch-all Routes & Path Resolution

- Implement `app/[...slug]/page.tsx` with `lynkow.paths.resolve()`
- Use `isContentResolve()` / `isCategoryResolve()` type guards
- Static generation with `lynkow.paths.list()` in `generateStaticParams()`
- Handle redirections with `lynkow.paths.matchRedirect()` in middleware
→ Guide: **Catch-all Routes & Path Resolution**

### 6. Dynamic Forms

- Fetch form schema with `lynkow.forms.getBySlug()`
- Render fields dynamically from `form.schema`
- Client-side validation from `field.validation`
- Submit with `lynkow.forms.submit()` (honeypot is automatic)
- Handle success vs pending (double opt-in)
- (optional) reCAPTCHA v3 integration if `form.recaptchaEnabled`
- Configure Preview URL for localhost development (avoids 403)
→ Guide: **Dynamic Forms**

### 7. Customer Reviews

- List reviews with `lynkow.reviews.list()`
- Display star ratings and author info
- Submit reviews with `lynkow.reviews.submit()`
- Handle moderation (pending vs approved)
- Check settings with `lynkow.reviews.settings()`
→ Guide: **Customer Reviews**

### 8. Media & Image Optimization

- Use `featuredImageVariants` presets (thumbnail, card, medium, content, hero, og)
- Build responsive images with `lynkow.media.srcset()`
- Single transforms with `lynkow.media.transform()`
- (optional) Custom Next.js Image loader
- (optional) Blur placeholder with tiny transform
→ Guide: **Media & Image Optimization**

### 9. Multi-language (optional)

- Set default locale in client config
- Per-request locale override: `{ locale: 'fr' }`
- Build locale switcher from `content.structuredData.alternates`
- Generate hreflang tags
- Static generation per locale with `paths.list({ locale })`
- (optional) Next.js middleware for locale detection
→ Guide: **Multi-language (i18n)**

### 10. Structured Content (optional)

- Detect structured content: `content.customData !== null`
- Fetch category schema for field type info
- Render richtext fields with `dangerouslySetInnerHTML`
- Handle image, select, array, object field types
→ Guide: **Structured Content**

### 11. SEO — Meta Tags & Structured Data

- `generateMetadata()` with `metaTitle`, `metaDescription`, `keywords`
- Open Graph: `ogImage`, `ogImageVariants`
- Canonical URLs: `canonicalUrl` with fallback
- JSON-LD: inject `content.structuredData.article.jsonLd`
- FAQ JSON-LD: inject `content.structuredData.faq.jsonLd` if present
→ Guide: **SEO & Analytics** (sections 1-4)

### 12. SEO — Sitemap, Robots, LLMs

- XML Sitemap: `app/sitemap.xml/route.ts` with `lynkow.seo.sitemap()`
- Robots.txt: `app/robots.txt/route.ts` with `lynkow.seo.robots()`
- llms.txt: `app/llms.txt/route.ts` with `lynkow.seo.llmsTxt()`
- llms-full.txt: `app/llms-full.txt/route.ts` with `lynkow.seo.llmsFullTxt()`
- Per-article Markdown: `.md` route with `lynkow.seo.getMarkdown()`
- Add `<link rel="alternate" href="/llms.txt">` in layout `<head>`
→ Guides: **SEO & Analytics** (sections 5-7) + **LLM-Ready Content**

### 13. Analytics

- Initialize tracker: `lynkow.analytics.init()`
- Track SPA navigation: `lynkow.analytics.trackPageview({ path })`
- (optional) Custom events: `lynkow.analytics.trackEvent()`
- **GDPR: If EU site, do NOT init without consent — see step 14**
→ Guide: **SEO & Analytics** (sections 8-9)

### 14. GDPR Cookie Consent

- Show consent banner: `lynkow.consent.show()`
- Conditional analytics: disable until consent granted
- Listen for changes: `lynkow.on('consent-changed', cb)`
- Enable/disable tracking based on `categories.analytics`
- (optional) Custom consent UI with `acceptAll()`, `rejectAll()`, `setCategories()`
→ Guide: **SEO & Analytics** (section 10)

### 15. Webhooks & Cache Revalidation

- Create webhook in admin: Settings > Webhooks
- Implement `app/api/revalidate/route.ts` handler
- Verify HMAC-SHA256 signature
- Map events to `revalidatePath()` / `revalidateTag()`
- Handle: content.published, content.updated, content.deleted, site_block.published
→ Guide: **Webhooks & Cache Revalidation**

### 16. Error Handling

- Use `isLynkowError()` type guard in catch blocks
- NOT_FOUND → `notFound()` in Next.js
- RATE_LIMITED → exponential backoff retry
- VALIDATION_ERROR → display field errors from `details[]`
- (optional) React Error Boundary
→ Guide: **Error Handling & Resilience**

### 17. Visual Editor (optional)

- Configure CSP headers: `frame-ancestors 'self' https://app.lynkow.com`
- Add `<LynkowVisualEditor cmsOrigin="...">` provider in layout
- Mark editable fields with `data-lynkow-block` and `data-lynkow-field`
- Use `useBlockData()` hook for live preview
- Set Preview URL in admin: Settings > Site
→ Guide: **Visual Editor**

### 18. Draft Preview (optional)

- Create preview entry route: `app/api/preview/route.ts`
- Create exit route: `app/api/preview/exit/route.ts`
- Fetch draft content via V1 API with Bearer token
- Use `draftMode().isEnabled` to branch rendering
→ Guide: **Draft Preview**

### 19. Search (optional)

- Server-side: `lynkow.search.query('term')`
- Client-side: autocomplete component
- Expose search endpoint for LLMs
→ Guide: **Instant Search**

---

## Commerce (optional)

Commerce endpoints need a **publishable key** in addition to the `siteId`. Copy it from the admin (Settings > Site Settings), it has the form `lkw_pk_` followed by 24 characters, and pass it once to the client. Every commerce call the client makes then carries it:

```typescript
const lynkow = createClient({ siteId, publishableKey: 'lkw_pk_...' })
```

A commerce call sent without the key throws a `LynkowError` with code `UNAUTHORIZED`. Skip this whole section if your site does not sell or take bookings.

### 20. Commerce: Product Catalog (optional)

- List products with `lynkow.products.list({ page, limit, kind, collection, category, search, sortBy, sortOrder })` (paginated: reads `data` + `meta`)
- Product page with `lynkow.products.getBySlug(idOrSlug)` (accepts a slug or a `prod_...` id); map `NOT_FOUND` to `notFound()`
- Display price from `priceCents / 100` with `currency`
- Accessible gallery from `product.gallery` (carries `alt` / `caption`), fall back to `title` when `alt` is null
- Variants from `product.variants` (each carries its own `priceCents`); empty array means the product-level price is the selling price
- Collections with `lynkow.productCollections.list()`, then `products.list({ collection: slug })` for a collection page
- Category tree with `lynkow.productCategories.tree()` (nesting via each node's `children`; a parent slug also matches its sub-categories)
→ Guide: **Product Catalog**

### 21. Commerce: Reservations (optional)

- Find bookable products with `lynkow.products.list({ kind: 'bookable' })`
- (optional) List formulas with `lynkow.reservations.offerings(idOrSlug)`; when the array is non-empty, `offeringId` becomes required downstream
- Check open slots with `lynkow.reservations.availability(idOrSlug, { from, to, offeringId? })` (dates `YYYY-MM-DD`, never cached)
- (optional) Let the buyer pick a resource with `lynkow.reservations.resources(idOrSlug)`; empty array means auto-assign, render no picker
- Create the booking with `lynkow.reservations.bookings.create(idOrSlug, { startsAt, partySize, guestName, guestEmail, offeringId?, resourceId? })`; no account needed, returns `confirmed` immediately
- On `VALIDATION_ERROR` (422), the slot may have filled after your availability read: re-fetch slots and let the buyer pick again
- Handle the auto anti-spam timing: a booking sent too fast throws `TOO_MANY_REQUESTS`, one sent more than ~1 hour after `createClient` throws `BAD_REQUEST`
- **Payment is taken on site by default.** Do NOT wire a checkout redirect into the default booking flow
- (optional, per-site) Online deposit: use `lynkow.reservations.book()` + `lynkow.reservations.refreshPayment()` ONLY when the deposit capability is enabled for your site (`bookings.create()` throws `CONFLICT` on a deposit product)
→ Guide: **Reservations and Deposits**

### 22. Commerce: Customer Accounts (optional)

- Two-step signup: `lynkow.customers.register({ email })`, then `lynkow.customers.activation.confirm({ token, password, acceptsTerms, ... })` from the emailed link
- Show ONE uniform message on `register`; never branch the UI on its outcome (that re-creates the account-enumeration signal the API removed)
- Login with `lynkow.customers.login({ email, password })`
- Persist the returned `token` yourself (e.g. an HttpOnly cookie) and seed it back via `createClient({ customerToken })`; the SDK holds it in memory only
- Current buyer and their bookings with `lynkow.customers.me()`
- Logout with `lynkow.customers.logout()`, or `logout({ everywhere: true })` to revoke every server-side session
- (optional) Address book: `lynkow.customers.addresses.{create,list,update,remove}`
- (optional) Marketing consent: `lynkow.customers.marketingConsent.{list,update}` (opt-out always wins)
- (optional) Forgotten password: `lynkow.customers.passwordReset.{request,confirm}`
→ Guide: **Customer Accounts**

---

## Admin Configuration Checklist

These steps are done in the Lynkow admin dashboard, not in code.

### Site Setup

- Site created with correct domain
- Preview URL set (Settings > Site) — required for forms, reviews, visual editor, and localhost development
- API Token created (Settings > API Tokens) — for webhooks and draft preview

### Content

- At least one category created
- Site Blocks created (header, footer, pages)
- Blog articles published

### SEO

- Sitemap settings configured (Settings > SEO)
- Robots.txt rules set
- llms.txt enabled with site description
- (optional) Sitemap sources added for multi-site setup (Settings > SEO > Sitemap > External Sitemaps)
- (optional) Redirections configured for URL changes (Settings > SEO > Redirects)

### Analytics & Consent

- Analytics enabled
- Consent mode set: **opt-in** for EU sites, **opt-out** for non-EU
- Cookie consent categories configured (necessary, analytics, marketing)
- (optional) Third-party scripts assigned to consent categories

### Webhooks

- Webhook URL configured pointing to your `/api/revalidate` endpoint
- Webhook secret set for HMAC-SHA256 verification
- Events selected: content.published, content.updated, content.deleted

### Visual Editor

- Preview URL set correctly (Settings > Site)
- Site Blocks have schemas matching your `data-lynkow-block` slugs

### Commerce (optional)

- Publishable key copied from Settings > Site Settings (`lkw_pk_...`) into your app config
- Products published (standard and/or bookable)
- For reservations: bookable products have offerings, availability windows, and any resource pool configured
- Customer accounts enabled if buyers need to sign in and see their bookings
- Online deposit / payment left OFF unless that capability is enabled for your site