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

# SDK Types: Content

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

# SDK Types: Content

> **Related services:** **ContentsService** — `lynkow.contents.getBySlug()`, `lynkow.contents.list()` | **TagsService** — `lynkow.tags.list()`

## `Author`

*Interface*

The author of a content item.
Corresponds to the user who created the content in the admin dashboard.

| Property | Type | Optional | Description |
| --- | --- | --- | --- |
| `avatarUrl` | `string \| null` | No | Absolute URL to the author's avatar image, or `null` if no avatar is set.<br>When available, points to an image hosted on the Lynkow CDN.<br>Use `ImageVariants.avatar` (128x128) for optimized display if available elsewhere. |
| `fullName` | `string` | No | The author's display name (e.g. `'Jane Doe'`).<br>This is the user's full name as set in their account profile. |
| `id` | `number` | No | Unique numeric user ID.<br>Stable across all content by the same author. |


---

## `Content`

*Interface*

Full content item with body, SEO metadata, structured data, and relations.
Returned by single-content endpoints (`GET /storefront/contents/:idOrSlug`).

Extends ContentSummary with all the fields omitted from list responses.

Extends: `ContentSummary`

| Property | Type | Optional | Description |
| --- | --- | --- | --- |
| `author` | `Author \| null` | No | The content author, or `null` if no author is assigned.<br>Corresponds to the admin user who created the content. |
| `body` | `string` | No | The article body as an HTML string, converted server-side from the TipTap editor format.<br>Render with `dangerouslySetInnerHTML` (React) or `v-html` (Vue).<br><br>For structured content (when the content belongs to a `'structured'` category),<br>this may be empty — use `customData` instead. |
| `canonicalUrl` | `string \| null` | No | Override canonical URL for this content. Max 1000 characters. Must be a valid URL.<br>`null` if not set — in that case, the canonical URL is the content's own `path`.<br>Use this when the same content is syndicated from another source. |
| `categories` | `Category[]` | No | Categories this content belongs to. At least one category is required for published content.<br>The first category in the array is the "primary" category used for URL path generation in nested mode.<br>May contain multiple categories for cross-listing purposes. |
| `createdAt` | `string` | No | ISO 8601 datetime when the content was created (e.g. `'2024-01-10T08:00:00.000+00:00'`).<br>Set automatically on initial creation and never changes. |
| `customData` | `Record<string, any> \| null` | Yes | Custom field data for structured content.<br>Populated when the content belongs to a category with `contentMode: 'structured'`.<br>The keys and value types are defined by the category's schema.<br>Richtext fields are automatically converted to HTML strings by the API.<br>`null` for standard content (which uses `body` instead). |
| `excerpt` | `string \| null` | No | Short summary text for previews and listing cards.<br>Either a manually written excerpt or auto-generated from the first ~160 characters of the body.<br>`null` if the content has no body text and no manual excerpt.<br>Plain text (no HTML). |
| `featuredImage` | `string \| null` | No | Absolute URL to the original (full-resolution) featured image.<br>`null` if no featured image is set for this content.<br>Prefer `featuredImageVariants` for optimized, CDN-resized versions. |
| `featuredImageVariants` | `ImageVariants` | Yes | CDN-optimized image variants of the featured image at multiple preset sizes.<br>`undefined` when no featured image is set or the site has no image transformations configured.<br><br>Available presets: `thumbnail` (400w), `card` (600w), `medium` (960w),<br>`content` (1200w), `hero` (1920w), `full` (2560w), all width-only and<br>aspect-ratio-preserving, plus `og` (1200x630, social-share ratio).<br><br>Use these instead of `featuredImage` for better performance and responsive layouts. |
| `id` | `number` | No | Unique numeric content ID. Auto-incremented.<br>Use this for API calls like `GET /storefront/contents/:id`. |
| `jsonLdExclusions` | `string[]` | Yes | Reserved `@id` values this content opts out of. Typically used to<br>suppress auto-generated nodes (e.g. `'auto:article'`) when a custom<br>replacement has been supplied in `jsonLdGraph`. |
| `jsonLdGraph` | `JsonLdNode[]` | Yes | Content-level cascade nodes declared by the admin or via the MCP<br>`create_content` / `update_content` tools. Merged with site + category<br>nodes server-side; consumers should read StructuredData.graph<br>instead of re-merging client-side.<br><br>See `/features/json-ld-cascade` in the Lynkow docs for the full model. |
| `keywords` | `string \| null` | No | Comma-separated SEO keywords (e.g. `'typescript, api, headless cms'`). Max 500 characters.<br>`null` if not set. Used for `<meta name="keywords">` tag.<br>Note: most search engines no longer use this for ranking, but it can be useful for internal search. |
| `locale` | `string` | No | BCP 47 locale code of this content (e.g. `'en'`, `'fr'`, `'es'`).<br>Matches one of the site's enabled locales.<br>When fetching content lists, this reflects the `locale` query parameter or the site's default locale. |
| `metaDescription` | `string \| null` | No | Custom meta description for SEO. Max 500 characters.<br>`null` if not set — consider using `excerpt` as a fallback for `<meta name="description">`.<br>Recommended length: 150-160 characters for optimal search engine display. |
| `metaTitle` | `string \| null` | No | Custom meta title for SEO. Max 255 characters.<br>`null` if not set — in that case, use `title` as a fallback for `<title>` and `og:title`. |
| `ogImage` | `string \| null` | No | Absolute URL to the Open Graph image for social sharing.<br>`null` if not set — falls back to the featured image when sharing on social platforms.<br>Max 1000 characters. Must be a valid URL. Recommended size: 1200x630px. |
| `ogImageVariants` | `ImageVariants` | Yes | CDN-optimized variants of the Open Graph image at multiple preset sizes.<br>`undefined` when no OG image is set.<br>Use the `og` variant (1200x630) for social sharing meta tags. |
| `path` | `string` | No | Full URL path including locale prefix, blog prefix, and category hierarchy.<br>Format depends on site configuration:<br>- Mono-language flat: `'/blog/my-article'`<br>- Multi-language flat: `'/en/blog/my-article'`<br>- Multi-language nested: `'/en/blog/parent-category/child-category/my-article'`<br><br>Use this to build links to the content on your frontend.<br>Does **not** include the domain — prepend your site's base URL. |
| `publishedAt` | `string` | No | ISO 8601 datetime when the content was published (e.g. `'2024-03-15T10:30:00.000+00:00'`).<br>Set when the content transitions from `draft` to `published` status.<br>Can also be manually set by editors to backdate or schedule content. |
| `slug` | `string` | No | URL-friendly slug, unique within the site for this locale.<br>Lowercase, hyphenated (e.g. `'my-article-title'`). Max 500 characters.<br>Can be used instead of `id` in API calls: `GET /storefront/contents/:slug`. |
| `status` | `"published"` | No | Publication status. Always `'published'` via the public API.<br>Draft, scheduled, and archived content is never returned by public endpoints. |
| `structuredData` | `StructuredData \| null` | No | Pre-generated structured data including Article JSON-LD, FAQ JSON-LD, and alternate language links.<br>`null` if structured data generation is disabled for this site or failed.<br><br>Inject each `jsonLd` object as a `<script type="application/ld+json">` tag in `<head>`. |
| `tags` | `Tag[]` | No | Tags associated with this content. Can be empty.<br>Tags are flat labels (no hierarchy) used for filtering and grouping content. |
| `title` | `string` | No | The content title in the requested locale.<br>Max 500 characters. Always non-empty for published content. |
| `updatedAt` | `string` | No | ISO 8601 datetime of the last modification (e.g. `'2024-06-01T14:00:00.000+00:00'`).<br>Updated whenever the content is saved, including metadata-only changes. |


---

## `ContentBody`

*TypeAlias*

Content body as an HTML string.

The API converts the TipTap editor's JSON content tree to HTML server-side,
so you receive a ready-to-render HTML string. This includes all formatting,
images, tables, code blocks, and FAQ blocks.

**Security note:** This HTML is generated server-side from the TipTap editor
and is safe to render. No user-submitted raw HTML is passed through.

```typescript
type ContentBody = string
```

---

## `ContentSummary`

*Interface*

Lightweight content representation returned in paginated list endpoints
(`GET /storefront/contents`).

Omits the full body, SEO fields, and relations to minimize payload size.
Use `Content` (from `GET /storefront/contents/:idOrSlug`) for the complete data.

| Property | Type | Optional | Description |
| --- | --- | --- | --- |
| `createdAt` | `string` | No | ISO 8601 datetime when the content was created (e.g. `'2024-01-10T08:00:00.000+00:00'`).<br>Set automatically on initial creation and never changes. |
| `excerpt` | `string \| null` | No | Short summary text for previews and listing cards.<br>Either a manually written excerpt or auto-generated from the first ~160 characters of the body.<br>`null` if the content has no body text and no manual excerpt.<br>Plain text (no HTML). |
| `featuredImage` | `string \| null` | No | Absolute URL to the original (full-resolution) featured image.<br>`null` if no featured image is set for this content.<br>Prefer `featuredImageVariants` for optimized, CDN-resized versions. |
| `featuredImageVariants` | `ImageVariants` | Yes | CDN-optimized image variants of the featured image at multiple preset sizes.<br>`undefined` when no featured image is set or the site has no image transformations configured.<br><br>Available presets: `thumbnail` (400w), `card` (600w), `medium` (960w),<br>`content` (1200w), `hero` (1920w), `full` (2560w), all width-only and<br>aspect-ratio-preserving, plus `og` (1200x630, social-share ratio).<br><br>Use these instead of `featuredImage` for better performance and responsive layouts. |
| `id` | `number` | No | Unique numeric content ID. Auto-incremented.<br>Use this for API calls like `GET /storefront/contents/:id`. |
| `locale` | `string` | No | BCP 47 locale code of this content (e.g. `'en'`, `'fr'`, `'es'`).<br>Matches one of the site's enabled locales.<br>When fetching content lists, this reflects the `locale` query parameter or the site's default locale. |
| `path` | `string` | No | Full URL path including locale prefix, blog prefix, and category hierarchy.<br>Format depends on site configuration:<br>- Mono-language flat: `'/blog/my-article'`<br>- Multi-language flat: `'/en/blog/my-article'`<br>- Multi-language nested: `'/en/blog/parent-category/child-category/my-article'`<br><br>Use this to build links to the content on your frontend.<br>Does **not** include the domain — prepend your site's base URL. |
| `publishedAt` | `string` | No | ISO 8601 datetime when the content was published (e.g. `'2024-03-15T10:30:00.000+00:00'`).<br>Set when the content transitions from `draft` to `published` status.<br>Can also be manually set by editors to backdate or schedule content. |
| `slug` | `string` | No | URL-friendly slug, unique within the site for this locale.<br>Lowercase, hyphenated (e.g. `'my-article-title'`). Max 500 characters.<br>Can be used instead of `id` in API calls: `GET /storefront/contents/:slug`. |
| `title` | `string` | No | The content title in the requested locale.<br>Max 500 characters. Always non-empty for published content. |


---

## `Tag`

*Interface*

A content tag used for cross-category classification and filtering.

Tags provide a flat (non-hierarchical) labeling system for content articles.
Unlike categories, tags have no parent-child relationships and are primarily
used for filtering and discovery. Use `contents.list({ tag: 'slug' })` to
fetch all articles with a specific tag.

| Property | Type | Optional | Description |
| --- | --- | --- | --- |
| `id` | `number` | No | Auto-incremented unique identifier.<br>Stable across locales -- the same tag has the same ID in all locale versions. |
| `locale` | `string` | No | Locale code for this tag instance (e.g. `'en'`, `'fr'`).<br>Tags are returned in the locale matching the request.<br>The same logical tag may have different `name` and `slug` values in each locale. |
| `name` | `string` | No | Display name of the tag (e.g. `'JavaScript'`, `'Getting Started'`).<br>Localized -- the value changes depending on the requested locale. |
| `slug` | `string` | No | URL-friendly slug derived from the tag name (e.g. `'javascript'`, `'getting-started'`).<br>Used as the filter value in `contents.list({ tag: slug })`.<br>Unique within a site + locale combination.<br>Localized -- each locale can have a different slug for the same tag. |


---

## `TipTapMark`

*Interface*

A TipTap inline mark (bold, italic, link, etc.) applied to text nodes.
Marks modify the visual presentation or semantics of text within a TipTap node.

You typically don't need to process these directly since the public API returns
pre-rendered HTML via `Content.body`. These types are provided for advanced use cases
like custom rendering pipelines.

| Property | Type | Optional | Description |
| --- | --- | --- | --- |
| `attrs` | `Record<string, unknown>` | Yes | Mark-specific attributes. For example:<br>- `link`: `{ href: 'https://...', target: '_blank' }`<br>- `textStyle`: `{ color: '#ff0000' }`<br><br>`undefined` for simple marks like `bold` or `italic` that have no attributes. |
| `type` | `string` | No | The mark type. Common built-in types include `'bold'`, `'italic'`, `'link'`,<br>`'code'`, `'strike'`, `'underline'`. Custom mark types may also appear as plain strings. |


---

## `TipTapNode`

*Interface*

A TipTap editor node representing a block or inline element in the content tree.

The public API returns pre-rendered HTML in `Content.body`, so you typically don't need
to process these nodes directly. These types are provided for advanced use cases like:

- Building a custom renderer (e.g. for React Native or email templates)
- Extracting specific content blocks (e.g. all images, all headings)
- Content analysis or transformation pipelines

| Property | Type | Optional | Description |
| --- | --- | --- | --- |
| `attrs` | `Record<string, unknown>` | Yes | Node-specific attributes. Examples:<br>- `heading`: `{ level: 2 }` (1-6)<br>- `image`: `{ src: '...', alt: '...', title: '...' }`<br>- `codeBlock`: `{ language: 'typescript' }`<br>- `tableCell`: `{ colspan: 1, rowspan: 1 }`<br><br>`undefined` for nodes that carry no attributes (e.g. `paragraph`, `listItem`). |
| `content` | `TipTapNode[]` | Yes | Ordered child nodes forming the content tree.<br>Block-level nodes (paragraphs, headings, lists) contain other nodes.<br>Leaf nodes like `'text'` and `'horizontalRule'` have no children. |
| `marks` | `TipTapMark[]` | Yes | Inline marks applied to this text node (bold, italic, link, etc.).<br>Only meaningful on `'text'` type nodes. Multiple marks can be combined<br>(e.g. bold + italic + link). |
| `text` | `string` | Yes | Text content, present **only** on `'text'` type nodes.<br>For all other node types, the textual content is in child `content` nodes. |
| `type` | `string` | No | The node type. Determines the semantic meaning and rendering behavior.<br>Common types: `'doc'` (root), `'paragraph'`, `'heading'`, `'text'`, `'image'`,<br>`'bulletList'`, `'orderedList'`, `'listItem'`, `'blockquote'`, `'codeBlock'`,<br>`'horizontalRule'`, `'table'`/`'tableRow'`/`'tableCell'`/`'tableHeader'`,<br>`'faqBlock'`/`'faqItem'`/`'faqQuestion'`/`'faqAnswer'`.<br>Custom node types may also appear as plain strings. |