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

# ProductsService

**Publié le** : 2026-08-20
**Catégorie** : Services

# ProductsService

Service for reading a site's published product catalogue.

Accessible via `lynkow.products`. Returns only PUBLISHED products. Requires a
publishable key: pass `publishableKey` to `createClient(...)` so every request
carries it (commerce routes reject calls without a valid key). Responses are
cached in-memory for 5 minutes (SHORT TTL) when a cache adapter is configured
on the client.

Access via: `lynkow.products`

## Methods

**2** methods

### `getBySlug`

```typescript
getBySlug(idOrSlug: string, options?: BaseRequestOptions): Promise<Product>
```

Retrieves a single published product by its `prod_...` wire id or its slug.
Cached for 5 minutes per id/slug.

Named `getBySlug` (not `get`) to match the SDK convention: `BaseService`
reserves a protected `get()` that the shared caching path dispatches to, so a
public `get()` on a service would hijack it. Mirrors `contents.getBySlug` and
`reviews.getBySlug`, both of which also accept an id or a slug.

| Parameter | Type | Description |
| --- | --- | --- |
| `idOrSlug` | `string` | The product's `prod_...` wire id or its URL slug. |
| `options` | `BaseRequestOptions` | Base request options (locale override, custom fetch options). |


Returns: `Promise<Product>`

```typescript
const product = await lynkow.products.getBySlug('sunset-dinner-cruise')
console.log(`${(product.priceCents / 100).toFixed(2)} ${product.currency}`)
```

```typescript
// Render an accessible, SEO-friendly gallery from the per-image metadata.
const product = await lynkow.products.getBySlug('sunset-dinner-cruise')

for (const image of product.gallery) {
  render(
    `<figure>
       <img src="${image.url}" alt="${image.alt ?? product.title}" />
       ${image.caption ? `<figcaption>${image.caption}</figcaption>` : ''}
     </figure>`
  )
}

// Existing code keeps working unchanged:
const urls: string[] = product.images
```

```typescript
// Render a variant selector, or fall back to the single product price.
const product = await lynkow.products.getBySlug('classic-tee')

if (product.variants.length > 0) {
  for (const variant of product.variants) {
    const label = variant.optionValues.map((ov) => ov.value).join(' / ')
    console.log(`${label}: ${(variant.priceCents / 100).toFixed(2)} ${product.currency}`)
  }
} else {
  // Single-price product: the product-level price is the selling price.
  console.log(`${(product.priceCents / 100).toFixed(2)} ${product.currency}`)
}
```

---

### `list`

```typescript
list(filters?: ProductsFilters, options?: BaseRequestOptions): Promise<ProductsListResponse>
```

Retrieves a paginated list of published products, sorted by creation date
(newest first by default). Cached for 5 minutes per unique filter combination.

| Parameter | Type | Description |
| --- | --- | --- |
| `filters` | `ProductsFilters` | Optional ProductsFilters: `page`/`limit`, `search`, `collection`, `category`, `kind`, `sortBy`/`sortOrder`. |
| `options` | `BaseRequestOptions` | Base request options (locale override, custom fetch options). |


Returns: `Promise<ProductsListResponse>`

```typescript
const { data, meta } = await lynkow.products.list({ page: 1, limit: 12, kind: 'bookable' })
```