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

# Quick Start

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

Get up and running with Lynkow in under 10 minutes. This guide walks you through installing the SDK, connecting to your site, and fetching your first content.

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

## Prerequisites

Before you begin, make sure you have:

- **Node.js 18+** installed ([download](https://nodejs.org/))
- A **Lynkow account** with at least one site created
- Your **Site ID** (found in your Lynkow dashboard under Site Settings)

## Installation

Install the Lynkow SDK from npm:

```bash
npm install lynkow
```

Or with your preferred package manager:

```bash
# yarn
yarn add lynkow

# pnpm
pnpm add lynkow
```

## Environment Setup

Create a `.env.local` file in the root of your project and add your Site ID:

```env
NEXT_PUBLIC_LYNKOW_SITE_ID=your-site-id-here
```

You can find your Site ID in the Lynkow dashboard by navigating to **Settings > General**. It is a UUID that looks like `a1b2c3d4-e5f6-7890-abcd-ef1234567890`.

## Create the SDK Client

Create a shared client instance that you will import throughout your application. This avoids re-initializing the client on every request.

Create the file `lib/lynkow.ts`:

```typescript
import { createClient } from 'lynkow'

export const lynkow = createClient({
  siteId: process.env.NEXT_PUBLIC_LYNKOW_SITE_ID!,
  // Optional: copied from the Lynkow dashboard, sent as the `X-Lynkow-Pk` header
  publishableKey: process.env.NEXT_PUBLIC_LYNKOW_PUBLISHABLE_KEY,
  fetchOptions: {
    next: { revalidate: 60 },
  },
})
```

**Configuration options:**

| Option | Type | Default | Description |
| --- | --- | --- | --- |
| `siteId` | `string` | *required* | Your Lynkow Site ID |
| `publishableKey` | `string` | `undefined` | Optional key copied from your Lynkow dashboard. Sent as the `X-Lynkow-Pk` header on every storefront API request |
| `locale` | `string` | `undefined` | Default locale for all requests (e.g., `'en'`, `'fr'`) |
| `fetchOptions` | `RequestInit` | `undefined` | Options passed to every `fetch` call (headers, cache, etc.) |
| `retry` | `RetryConfig \| boolean` | `true` | Auto-retry transient failures (429/503/network) on reads with backoff, honoring `Retry-After`. Set `false` to disable |


The SDK connects to `https://api.lynkow.com` by default. The `revalidate: 60` setting tells Next.js to cache responses and revalidate them every 60 seconds via ISR. For near-instant updates, add a webhook endpoint (see [Guide 11: Webhooks & Cache Revalidation](/docs/sdk/advanced/webhooks-revalidation)).

## First API Call: List Articles

Create a page that fetches and displays your published articles.

Create the file `app/blog/page.tsx`:

```tsx
import { lynkow } from '@/lib/lynkow'

export default async function BlogPage() {
  const { data: articles, meta } = await lynkow.contents.list({
    limit: 10,
    sort: 'published_at',
    order: 'desc',
  })

  return (
    <main style={{ maxWidth: '800px', margin: '0 auto', padding: '2rem' }}>
      <h1>Blog</h1>
      <p>{meta.total} articles published</p>

      <ul style={{ listStyle: 'none', padding: 0 }}>
        {articles.map((article) => (
          <li key={article.id} style={{ marginBottom: '2rem' }}>
            <a href={`/blog/${article.slug}`}>
              <h2>{article.title}</h2>
            </a>
            {article.excerpt && <p>{article.excerpt}</p>}
            <time dateTime={article.publishedAt}>
              {new Date(article.publishedAt).toLocaleDateString()}
            </time>
          </li>
        ))}
      </ul>

      <p>
        Page {meta.currentPage} of {meta.lastPage}
      </p>
    </main>
  )
}
```

The `contents.list()` method returns published articles with pagination metadata. Each article in the list includes its `id`, `title`, `slug`, `path`, `excerpt`, `featuredImage`, `publishedAt`, and `locale` -- but not the full body HTML, which keeps list responses fast.

## Display a Single Article

Create a dynamic route to display a full article by its slug.

Create the file `app/blog/[slug]/page.tsx`:

```tsx
import { lynkow } from '@/lib/lynkow'
import { notFound } from 'next/navigation'

type Params = Promise<{ slug: string }>

export default async function ArticlePage({ params }: { params: Params }) {
  const { slug } = await params

  let article
  try {
    article = await lynkow.contents.getBySlug(slug)
  } catch {
    notFound()
  }

  return (
    <main style={{ maxWidth: '800px', margin: '0 auto', padding: '2rem' }}>
      <article>
        <h1>{article.title}</h1>

        {article.author && (
          <p>
            By {article.author.fullName} &middot;{' '}
            <time dateTime={article.publishedAt}>
              {new Date(article.publishedAt).toLocaleDateString()}
            </time>
          </p>
        )}

        {article.featuredImage && (
          <img
            src={article.featuredImageVariants?.hero || article.featuredImage}
            alt={article.title}
            style={{ width: '100%', height: 'auto', borderRadius: '8px' }}
          />
        )}

        <div dangerouslySetInnerHTML={{ __html: article.body }} />

        {article.categories.length > 0 && (
          <div>
            <strong>Categories:</strong>{' '}
            {article.categories.map((cat) => cat.name).join(', ')}
          </div>
        )}

        {article.tags.length > 0 && (
          <div>
            <strong>Tags:</strong>{' '}
            {article.tags.map((tag) => tag.name).join(', ')}
          </div>
        )}
      </article>
    </main>
  )
}
```

The `contents.getBySlug()` method returns the full content object including the rendered HTML `body`, `author`, `categories`, `tags`, `structuredData`, and SEO fields like `metaTitle` and `metaDescription`.

## Understanding the Response Types

### ContentSummary (returned by `contents.list()`)

Lightweight representation used in listing pages. The listing example above reads these fields:

```typescript
interface ContentSummary {
  id: string
  title: string
  slug: string
  excerpt: string | null
  publishedAt: string
  // ...more fields
}
```

See the full `ContentSummary` shape in the [SDK Types reference](/docs/sdk/types).

### Content (returned by `contents.getBySlug()`)

Full content with body and relationships. The single-article example above reads these fields:

```typescript
interface Content {
  title: string
  body: string                    // Rendered HTML
  publishedAt: string
  featuredImage: string | null
  featuredImageVariants: Record<string, string> | null
  author: { fullName: string } | null
  categories: Array<{ name: string }>
  tags: Array<{ name: string }>
  // ...more fields (structuredData, metaTitle, metaDescription, ogImage, ...)
}
```

See the full `Content` shape in the [SDK Types reference](/docs/sdk/types).

### PaginationMeta

Returned as `meta` in paginated responses. The example above reads these fields:

```typescript
interface PaginationMeta {
  total: number
  currentPage: number
  lastPage: number
  // ...more fields
}
```

See the full `PaginationMeta` shape in the [SDK Types reference](/docs/sdk/types).

## Next Steps

You now have a working integration with Lynkow. Here is where to go from here:

- **[Build a Complete Blog with Next.js](/docs/sdk/getting-started/blog-nextjs)** -- Full blog implementation with categories, tags, pagination, SEO metadata, JSON-LD, and responsive images.
- **[API Reference](/docs/sdk)** -- Complete documentation of all SDK methods and response types.
- **[Media & Images](/docs/sdk/media-seo/media-images)** -- Learn how to use `lynkow.media.srcset()` and `lynkow.media.transform()` for responsive, optimized images.
- **[Localization](/docs/sdk/features/i18n)** -- Serve content in multiple languages with locale-aware queries.