lynkow 3.6.2 → 3.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -9,6 +9,7 @@ Official TypeScript SDK for [Lynkow](https://lynkow.com) Headless CMS.
9
9
  - **Framework-agnostic** - Works with Next.js, Nuxt, Astro, SvelteKit, etc.
10
10
  - **Tree-shakeable** - Only import what you need
11
11
  - **Isomorphic** - Works on both browser and server (Node.js, Deno, Bun)
12
+ - **Image Transformations** - Cloudflare CDN srcset and responsive image helpers
12
13
  - **Built-in Analytics** - Page views, events, and funnel tracking
13
14
  - **Cookie Consent** - GDPR-compliant consent banner with preferences
14
15
  - **Spam protection** - Built-in honeypot fields for form submissions
@@ -129,6 +130,7 @@ The SDK is isomorphic and works on both browser and server environments. Some fe
129
130
  | Feature | Browser | Server |
130
131
  |---------|---------|--------|
131
132
  | Contents, Categories, Pages... | ✅ | ✅ |
133
+ | Media (image transformations) | ✅ | ✅ |
132
134
  | Forms, Reviews | ✅ | ✅ |
133
135
  | Analytics tracking | ✅ | ❌ (no-op) |
134
136
  | Consent banner | ✅ | ❌ (no-op) |
@@ -327,6 +329,72 @@ if (redirect) {
327
329
  }
328
330
  ```
329
331
 
332
+ ### Media (Image Transformations)
333
+
334
+ Build optimized image URLs using Cloudflare Image Transformations.
335
+
336
+ ```typescript
337
+ // Build a srcset for responsive images
338
+ const srcset = lynkow.media.srcset(content.featuredImage)
339
+ // => "https://cdn.../cdn-cgi/image/w=400,.../photo.jpg 400w, ...800w, ...1200w, ...1920w"
340
+
341
+ // Custom widths and options
342
+ const srcset = lynkow.media.srcset(content.featuredImage, {
343
+ widths: [320, 640, 960],
344
+ fit: 'cover',
345
+ quality: 85,
346
+ gravity: '0.5x0.3', // focal point
347
+ })
348
+
349
+ // Build a single transformed URL
350
+ const url = lynkow.media.transform(content.featuredImage, {
351
+ w: 800,
352
+ h: 600,
353
+ fit: 'cover',
354
+ format: 'webp',
355
+ quality: 85,
356
+ })
357
+ ```
358
+
359
+ #### Using with `<img>` tags
360
+
361
+ ```jsx
362
+ // Simple: use pre-computed variants from the API
363
+ <img
364
+ src={content.featuredImageVariants?.card || content.featuredImage}
365
+ alt={content.title}
366
+ />
367
+
368
+ // Advanced: build srcset for fully responsive images
369
+ <img
370
+ src={content.featuredImage}
371
+ srcSet={lynkow.media.srcset(content.featuredImage)}
372
+ sizes="(max-width: 768px) 100vw, 800px"
373
+ alt={content.title}
374
+ />
375
+ ```
376
+
377
+ #### API Response Variants
378
+
379
+ The API automatically includes pre-computed image variants:
380
+
381
+ | Field | Available on | Presets |
382
+ |-------|-------------|---------|
383
+ | `featuredImageVariants` | Content | `thumbnail`, `card`, `hero`, `og` |
384
+ | `ogImageVariants` | Content | `og` |
385
+ | `imageVariants` | Category | `thumbnail`, `card`, `og` |
386
+
387
+ ```typescript
388
+ // Use variants directly (no SDK helper needed)
389
+ const thumbnailUrl = content.featuredImageVariants?.thumbnail
390
+ const heroUrl = content.featuredImageVariants?.hero
391
+
392
+ // Category images
393
+ const categoryImg = category.imageVariants?.card
394
+ ```
395
+
396
+ > **Note**: Body HTML (`content.body`) already includes `srcset`, `loading="lazy"`, and `decoding="async"` on images automatically. No client-side processing needed.
397
+
330
398
  ## Analytics (Browser-only)
331
399
 
332
400
  The SDK includes built-in analytics that loads the Lynkow tracker automatically.
@@ -515,7 +583,23 @@ function Article({ content }) {
515
583
  }
516
584
  ```
517
585
 
518
- > ⚠️ **Important**: The `attributesToProps` function automatically converts `style="text-align: center"` to `{ style: { textAlign: 'center' } }`. Without this, inline styles will be lost and text alignment won't work.
586
+ > ⚠️ **Important**: The `attributesToProps` function automatically converts HTML attributes to React props (e.g. `style="text-align: center"` `{ style: { textAlign: 'center' } }`, `id="pricing"` → `{ id: 'pricing' }`). Without this, inline styles, anchors, and other native attributes will be lost.
587
+
588
+ ### HTML Anchors (Block IDs)
589
+
590
+ Editors can set custom HTML `id` attributes on any block element (headings, paragraphs, blockquotes, images, etc.) from the editor's bubble menu. The API renders these as standard `id` attributes in the HTML:
591
+
592
+ ```html
593
+ <h2 id="pricing">Pricing</h2>
594
+ <p id="intro">Welcome to our platform.</p>
595
+ ```
596
+
597
+ This enables:
598
+ - **Anchor links**: `<a href="#pricing">Jump to Pricing</a>`
599
+ - **URL fragments**: `https://example.com/article#pricing`
600
+ - **Scroll-to**: `document.getElementById('pricing')?.scrollIntoView()`
601
+
602
+ > ⚠️ **Important**: If you use `html-react-parser` with a custom `replace` function, you **must** spread `attributesToProps(domNode.attribs)` on your elements to preserve `id` attributes. Without `{...props}`, anchor IDs will be stripped from the rendered output.
519
603
 
520
604
  ### Code Block HTML Structure
521
605
 
@@ -961,6 +1045,11 @@ import type {
961
1045
  Review,
962
1046
  Tag,
963
1047
 
1048
+ // Images
1049
+ ImageVariants,
1050
+ SrcsetOptions,
1051
+ TransformOptions,
1052
+
964
1053
  // Config
965
1054
  LynkowConfig,
966
1055
  ClientConfig,
@@ -1018,6 +1107,12 @@ import type {
1018
1107
  - **Site config alignment**: API now returns both flat fields (`defaultLocale`, `enabledLocales`) and rich `i18n` object
1019
1108
  - **Next.js App Router documentation**: Comprehensive guide for Server Components and cookie-based i18n
1020
1109
 
1110
+ ### New in v3.7
1111
+
1112
+ - **Image Transformations**: New `lynkow.media` service with `srcset()` and `transform()` helpers for Cloudflare Image Transformations
1113
+ - **ImageVariants type**: API responses now include pre-computed `featuredImageVariants`, `ogImageVariants`, and `imageVariants` fields
1114
+ - **Body HTML srcset**: Content body images automatically include `srcset`, `loading="lazy"`, and `decoding="async"` attributes
1115
+
1021
1116
  ### Upgrade Steps
1022
1117
 
1023
1118
  ```typescript
package/dist/index.d.mts CHANGED
@@ -95,7 +95,7 @@ declare class ContentsService extends BaseService {
95
95
  * ```typescript
96
96
  * const { data, meta } = await lynkow.contents.list({
97
97
  * page: 1,
98
- * perPage: 10,
98
+ * limit: 10,
99
99
  * category: 'tech'
100
100
  * })
101
101
  * ```
@@ -160,7 +160,7 @@ declare class CategoriesService extends BaseService {
160
160
  * ```typescript
161
161
  * const { category, contents } = await lynkow.categories.getBySlug('tech', {
162
162
  * page: 1,
163
- * perPage: 10
163
+ * limit: 10
164
164
  * })
165
165
  * ```
166
166
  */
@@ -377,7 +377,7 @@ declare class ReviewsService extends BaseService {
377
377
  * ```typescript
378
378
  * const { data, meta } = await lynkow.reviews.list({
379
379
  * minRating: 4,
380
- * perPage: 10
380
+ * limit: 10
381
381
  * })
382
382
  * ```
383
383
  */
@@ -708,6 +708,29 @@ interface LynkowClient {
708
708
  paths: PathsService;
709
709
  }
710
710
 
711
+ /**
712
+ * Image transformation variant URLs generated by Cloudflare Image Transformations.
713
+ * Each key corresponds to a preset name.
714
+ */
715
+ interface ImageVariants {
716
+ /** 400x300, cover, sharpen (list thumbnails) */
717
+ thumbnail?: string;
718
+ /** 600x400, cover (card layouts) */
719
+ card?: string;
720
+ /** 1200w, scale-down (article body) */
721
+ content?: string;
722
+ /** 960w, scale-down (medium displays) */
723
+ medium?: string;
724
+ /** 1920w, scale-down (hero banners) */
725
+ hero?: string;
726
+ /** 1200x630, cover (Open Graph / social sharing) */
727
+ og?: string;
728
+ /** 128x128, cover + face gravity (avatars) */
729
+ avatar?: string;
730
+ /** 2560w, scale-down (full resolution) */
731
+ full?: string;
732
+ }
733
+
711
734
  /**
712
735
  * Content category
713
736
  */
@@ -733,6 +756,8 @@ interface CategoryWithCount extends Category {
733
756
  image: string | null;
734
757
  /** Number of contents in this category */
735
758
  contentCount: number;
759
+ /** CDN image variants */
760
+ imageVariants?: ImageVariants;
736
761
  }
737
762
  /**
738
763
  * Detailed category (with all info)
@@ -902,6 +927,7 @@ interface ContentSummary {
902
927
  path: string;
903
928
  excerpt: string | null;
904
929
  featuredImage: string | null;
930
+ featuredImageVariants?: ImageVariants;
905
931
  locale: string;
906
932
  publishedAt: string;
907
933
  createdAt: string;
@@ -926,6 +952,8 @@ interface Content extends ContentSummary {
926
952
  canonicalUrl: string | null;
927
953
  /** Open Graph image */
928
954
  ogImage: string | null;
955
+ /** Open Graph image CDN variants */
956
+ ogImageVariants?: ImageVariants;
929
957
  /** JSON-LD structured data */
930
958
  structuredData: StructuredData | null;
931
959
  /** Article author */
@@ -1578,6 +1606,11 @@ interface PaginationOptions {
1578
1606
  /** Page number */
1579
1607
  page?: number;
1580
1608
  /** Elements per page */
1609
+ limit?: number;
1610
+ /**
1611
+ * Elements per page
1612
+ * @deprecated Use `limit` instead
1613
+ */
1581
1614
  perPage?: number;
1582
1615
  }
1583
1616
  /**
@@ -1984,6 +2017,82 @@ declare class EnhancementsService {
1984
2017
  destroy(): void;
1985
2018
  }
1986
2019
 
2020
+ /**
2021
+ * Options for building srcset URLs
2022
+ */
2023
+ interface SrcsetOptions {
2024
+ /** Image widths to include in srcset (default: [400, 800, 1200, 1920]) */
2025
+ widths?: number[];
2026
+ /** Resize fit mode (default: 'scale-down') */
2027
+ fit?: 'cover' | 'contain' | 'scale-down' | 'crop';
2028
+ /** Image quality 1-100 (default: 80) */
2029
+ quality?: number;
2030
+ /** Focal point for crop (e.g., '0.5x0.3') */
2031
+ gravity?: string;
2032
+ }
2033
+ /**
2034
+ * Options for building a single transformed URL
2035
+ */
2036
+ interface TransformOptions {
2037
+ /** Target width in pixels */
2038
+ w?: number;
2039
+ /** Target height in pixels */
2040
+ h?: number;
2041
+ /** Resize fit mode */
2042
+ fit?: 'cover' | 'contain' | 'scale-down' | 'crop';
2043
+ /** Image quality 1-100 (default: 80) */
2044
+ quality?: number;
2045
+ /** Output format (default: 'auto') */
2046
+ format?: 'auto' | 'webp' | 'avif' | 'jpeg';
2047
+ /** Focal point for crop */
2048
+ gravity?: string;
2049
+ /** Device Pixel Ratio 1-4 */
2050
+ dpr?: number;
2051
+ }
2052
+ /**
2053
+ * Service for working with Cloudflare Image Transformation URLs.
2054
+ *
2055
+ * This service helps build optimized image URLs client-side.
2056
+ * It works with any image URL from the Lynkow API.
2057
+ *
2058
+ * @example
2059
+ * ```typescript
2060
+ * const lynkow = createClient({ siteId: '...' })
2061
+ *
2062
+ * // Build srcset for responsive images
2063
+ * const srcset = lynkow.media.srcset(content.featuredImage)
2064
+ *
2065
+ * // Build a single transformed URL
2066
+ * const url = lynkow.media.transform(content.featuredImage, { w: 800 })
2067
+ * ```
2068
+ */
2069
+ declare class MediaHelperService {
2070
+ /**
2071
+ * Generates an HTML `srcset` attribute value from an image URL.
2072
+ *
2073
+ * @param imageUrl - Original image URL from the Lynkow API
2074
+ * @param options - Srcset configuration
2075
+ * @returns srcset string ready for use in an `<img>` tag, or empty string if URL is invalid
2076
+ */
2077
+ srcset(imageUrl: string | null | undefined, options?: SrcsetOptions): string;
2078
+ /**
2079
+ * Generates a single transformed image URL.
2080
+ *
2081
+ * @param imageUrl - Original image URL from the Lynkow API
2082
+ * @param options - Transformation options
2083
+ * @returns Transformed URL, or the original URL if transformation is not possible
2084
+ */
2085
+ transform(imageUrl: string | null | undefined, options?: TransformOptions): string;
2086
+ /**
2087
+ * Extracts the CDN base and relative path from a Lynkow image URL.
2088
+ *
2089
+ * Handles both original URLs and already-transformed URLs.
2090
+ *
2091
+ * @returns Parsed URL parts, or null if the URL is not a valid Lynkow CDN URL
2092
+ */
2093
+ private parseImageUrl;
2094
+ }
2095
+
1987
2096
  /**
1988
2097
  * Lynkow SDK Client
1989
2098
  * Main entry point for the SDK
@@ -2064,6 +2173,11 @@ interface Client extends LynkowClient {
2064
2173
  * Content enhancements service (code copy, etc.)
2065
2174
  */
2066
2175
  enhancements: EnhancementsService;
2176
+ /**
2177
+ * Image transformation helpers.
2178
+ * Use these to build optimized image URLs for responsive images.
2179
+ */
2180
+ readonly media: MediaHelperService;
2067
2181
  }
2068
2182
  /**
2069
2183
  * Creates a Lynkow client instance (SDK v3)
@@ -2213,4 +2327,4 @@ declare function browserOnly<T>(fn: () => T, fallback: T): T;
2213
2327
  */
2214
2328
  declare function browserOnlyAsync<T>(fn: () => Promise<T>, fallback: T): Promise<T>;
2215
2329
 
2216
- export { type Alternate, type ApiErrorDetail, type Author, type BaseRequestOptions, type CategoriesListResponse, type Category, type CategoryDetail, type CategoryDetailResponse, type CategoryOptions, type CategoryResolveResponse, type CategoryTreeNode, type CategoryTreeResponse, type CategoryWithCount, type Client, type ClientConfig, type ConsentCategories, type ConsentLogResponse, type Content, type ContentBody, type ContentResolveResponse, type ContentSummary, type ContentsFilters, type ContentsListResponse, type CookieCategory, type CookieConfig, type CookiePreferences, type CookieTexts, EnhancementsService, type ErrorCode, type EventData, type EventName, type Form, type FormField, type FormFieldOption, type FormFieldType, type FormFieldValidation, type FormSettings, type FormSubmitData, type FormSubmitResponse, type FunnelStepData, type GlobalBlock, type GlobalBlockResponse, type LegalDocument, type LynkowClient, type LynkowConfig, LynkowError, type LynkowEvents, type Page, type PageSeo, type PageSummary, type PagesListResponse, type PageviewData, type PaginatedResponse, type PaginationMeta, type PaginationOptions, type Path, type PathsListResponse, type Redirect, type ResolveResponse, type Review, type ReviewResponse, type ReviewSettings, type ReviewSubmitData, type ReviewSubmitResponse, type ReviewsFilters, type ReviewsListResponse, type SiteConfig, type SiteConfigResponse, type SortOptions, type SubmitOptions, type Tag, type TagsListResponse, type TipTapMark, type TipTapNode, browserOnly, browserOnlyAsync, createClient, createLynkowClient, isBrowser, isCategoryResolve, isContentResolve, isLynkowError, isServer };
2330
+ export { type Alternate, type ApiErrorDetail, type Author, type BaseRequestOptions, type CategoriesListResponse, type Category, type CategoryDetail, type CategoryDetailResponse, type CategoryOptions, type CategoryResolveResponse, type CategoryTreeNode, type CategoryTreeResponse, type CategoryWithCount, type Client, type ClientConfig, type ConsentCategories, type ConsentLogResponse, type Content, type ContentBody, type ContentResolveResponse, type ContentSummary, type ContentsFilters, type ContentsListResponse, type CookieCategory, type CookieConfig, type CookiePreferences, type CookieTexts, EnhancementsService, type ErrorCode, type EventData, type EventName, type Form, type FormField, type FormFieldOption, type FormFieldType, type FormFieldValidation, type FormSettings, type FormSubmitData, type FormSubmitResponse, type FunnelStepData, type GlobalBlock, type GlobalBlockResponse, type ImageVariants, type LegalDocument, type LynkowClient, type LynkowConfig, LynkowError, type LynkowEvents, MediaHelperService, type Page, type PageSeo, type PageSummary, type PagesListResponse, type PageviewData, type PaginatedResponse, type PaginationMeta, type PaginationOptions, type Path, type PathsListResponse, type Redirect, type ResolveResponse, type Review, type ReviewResponse, type ReviewSettings, type ReviewSubmitData, type ReviewSubmitResponse, type ReviewsFilters, type ReviewsListResponse, type SiteConfig, type SiteConfigResponse, type SortOptions, type SrcsetOptions, type SubmitOptions, type Tag, type TagsListResponse, type TipTapMark, type TipTapNode, type TransformOptions, browserOnly, browserOnlyAsync, createClient, createLynkowClient, isBrowser, isCategoryResolve, isContentResolve, isLynkowError, isServer };
package/dist/index.d.ts CHANGED
@@ -95,7 +95,7 @@ declare class ContentsService extends BaseService {
95
95
  * ```typescript
96
96
  * const { data, meta } = await lynkow.contents.list({
97
97
  * page: 1,
98
- * perPage: 10,
98
+ * limit: 10,
99
99
  * category: 'tech'
100
100
  * })
101
101
  * ```
@@ -160,7 +160,7 @@ declare class CategoriesService extends BaseService {
160
160
  * ```typescript
161
161
  * const { category, contents } = await lynkow.categories.getBySlug('tech', {
162
162
  * page: 1,
163
- * perPage: 10
163
+ * limit: 10
164
164
  * })
165
165
  * ```
166
166
  */
@@ -377,7 +377,7 @@ declare class ReviewsService extends BaseService {
377
377
  * ```typescript
378
378
  * const { data, meta } = await lynkow.reviews.list({
379
379
  * minRating: 4,
380
- * perPage: 10
380
+ * limit: 10
381
381
  * })
382
382
  * ```
383
383
  */
@@ -708,6 +708,29 @@ interface LynkowClient {
708
708
  paths: PathsService;
709
709
  }
710
710
 
711
+ /**
712
+ * Image transformation variant URLs generated by Cloudflare Image Transformations.
713
+ * Each key corresponds to a preset name.
714
+ */
715
+ interface ImageVariants {
716
+ /** 400x300, cover, sharpen (list thumbnails) */
717
+ thumbnail?: string;
718
+ /** 600x400, cover (card layouts) */
719
+ card?: string;
720
+ /** 1200w, scale-down (article body) */
721
+ content?: string;
722
+ /** 960w, scale-down (medium displays) */
723
+ medium?: string;
724
+ /** 1920w, scale-down (hero banners) */
725
+ hero?: string;
726
+ /** 1200x630, cover (Open Graph / social sharing) */
727
+ og?: string;
728
+ /** 128x128, cover + face gravity (avatars) */
729
+ avatar?: string;
730
+ /** 2560w, scale-down (full resolution) */
731
+ full?: string;
732
+ }
733
+
711
734
  /**
712
735
  * Content category
713
736
  */
@@ -733,6 +756,8 @@ interface CategoryWithCount extends Category {
733
756
  image: string | null;
734
757
  /** Number of contents in this category */
735
758
  contentCount: number;
759
+ /** CDN image variants */
760
+ imageVariants?: ImageVariants;
736
761
  }
737
762
  /**
738
763
  * Detailed category (with all info)
@@ -902,6 +927,7 @@ interface ContentSummary {
902
927
  path: string;
903
928
  excerpt: string | null;
904
929
  featuredImage: string | null;
930
+ featuredImageVariants?: ImageVariants;
905
931
  locale: string;
906
932
  publishedAt: string;
907
933
  createdAt: string;
@@ -926,6 +952,8 @@ interface Content extends ContentSummary {
926
952
  canonicalUrl: string | null;
927
953
  /** Open Graph image */
928
954
  ogImage: string | null;
955
+ /** Open Graph image CDN variants */
956
+ ogImageVariants?: ImageVariants;
929
957
  /** JSON-LD structured data */
930
958
  structuredData: StructuredData | null;
931
959
  /** Article author */
@@ -1578,6 +1606,11 @@ interface PaginationOptions {
1578
1606
  /** Page number */
1579
1607
  page?: number;
1580
1608
  /** Elements per page */
1609
+ limit?: number;
1610
+ /**
1611
+ * Elements per page
1612
+ * @deprecated Use `limit` instead
1613
+ */
1581
1614
  perPage?: number;
1582
1615
  }
1583
1616
  /**
@@ -1984,6 +2017,82 @@ declare class EnhancementsService {
1984
2017
  destroy(): void;
1985
2018
  }
1986
2019
 
2020
+ /**
2021
+ * Options for building srcset URLs
2022
+ */
2023
+ interface SrcsetOptions {
2024
+ /** Image widths to include in srcset (default: [400, 800, 1200, 1920]) */
2025
+ widths?: number[];
2026
+ /** Resize fit mode (default: 'scale-down') */
2027
+ fit?: 'cover' | 'contain' | 'scale-down' | 'crop';
2028
+ /** Image quality 1-100 (default: 80) */
2029
+ quality?: number;
2030
+ /** Focal point for crop (e.g., '0.5x0.3') */
2031
+ gravity?: string;
2032
+ }
2033
+ /**
2034
+ * Options for building a single transformed URL
2035
+ */
2036
+ interface TransformOptions {
2037
+ /** Target width in pixels */
2038
+ w?: number;
2039
+ /** Target height in pixels */
2040
+ h?: number;
2041
+ /** Resize fit mode */
2042
+ fit?: 'cover' | 'contain' | 'scale-down' | 'crop';
2043
+ /** Image quality 1-100 (default: 80) */
2044
+ quality?: number;
2045
+ /** Output format (default: 'auto') */
2046
+ format?: 'auto' | 'webp' | 'avif' | 'jpeg';
2047
+ /** Focal point for crop */
2048
+ gravity?: string;
2049
+ /** Device Pixel Ratio 1-4 */
2050
+ dpr?: number;
2051
+ }
2052
+ /**
2053
+ * Service for working with Cloudflare Image Transformation URLs.
2054
+ *
2055
+ * This service helps build optimized image URLs client-side.
2056
+ * It works with any image URL from the Lynkow API.
2057
+ *
2058
+ * @example
2059
+ * ```typescript
2060
+ * const lynkow = createClient({ siteId: '...' })
2061
+ *
2062
+ * // Build srcset for responsive images
2063
+ * const srcset = lynkow.media.srcset(content.featuredImage)
2064
+ *
2065
+ * // Build a single transformed URL
2066
+ * const url = lynkow.media.transform(content.featuredImage, { w: 800 })
2067
+ * ```
2068
+ */
2069
+ declare class MediaHelperService {
2070
+ /**
2071
+ * Generates an HTML `srcset` attribute value from an image URL.
2072
+ *
2073
+ * @param imageUrl - Original image URL from the Lynkow API
2074
+ * @param options - Srcset configuration
2075
+ * @returns srcset string ready for use in an `<img>` tag, or empty string if URL is invalid
2076
+ */
2077
+ srcset(imageUrl: string | null | undefined, options?: SrcsetOptions): string;
2078
+ /**
2079
+ * Generates a single transformed image URL.
2080
+ *
2081
+ * @param imageUrl - Original image URL from the Lynkow API
2082
+ * @param options - Transformation options
2083
+ * @returns Transformed URL, or the original URL if transformation is not possible
2084
+ */
2085
+ transform(imageUrl: string | null | undefined, options?: TransformOptions): string;
2086
+ /**
2087
+ * Extracts the CDN base and relative path from a Lynkow image URL.
2088
+ *
2089
+ * Handles both original URLs and already-transformed URLs.
2090
+ *
2091
+ * @returns Parsed URL parts, or null if the URL is not a valid Lynkow CDN URL
2092
+ */
2093
+ private parseImageUrl;
2094
+ }
2095
+
1987
2096
  /**
1988
2097
  * Lynkow SDK Client
1989
2098
  * Main entry point for the SDK
@@ -2064,6 +2173,11 @@ interface Client extends LynkowClient {
2064
2173
  * Content enhancements service (code copy, etc.)
2065
2174
  */
2066
2175
  enhancements: EnhancementsService;
2176
+ /**
2177
+ * Image transformation helpers.
2178
+ * Use these to build optimized image URLs for responsive images.
2179
+ */
2180
+ readonly media: MediaHelperService;
2067
2181
  }
2068
2182
  /**
2069
2183
  * Creates a Lynkow client instance (SDK v3)
@@ -2213,4 +2327,4 @@ declare function browserOnly<T>(fn: () => T, fallback: T): T;
2213
2327
  */
2214
2328
  declare function browserOnlyAsync<T>(fn: () => Promise<T>, fallback: T): Promise<T>;
2215
2329
 
2216
- export { type Alternate, type ApiErrorDetail, type Author, type BaseRequestOptions, type CategoriesListResponse, type Category, type CategoryDetail, type CategoryDetailResponse, type CategoryOptions, type CategoryResolveResponse, type CategoryTreeNode, type CategoryTreeResponse, type CategoryWithCount, type Client, type ClientConfig, type ConsentCategories, type ConsentLogResponse, type Content, type ContentBody, type ContentResolveResponse, type ContentSummary, type ContentsFilters, type ContentsListResponse, type CookieCategory, type CookieConfig, type CookiePreferences, type CookieTexts, EnhancementsService, type ErrorCode, type EventData, type EventName, type Form, type FormField, type FormFieldOption, type FormFieldType, type FormFieldValidation, type FormSettings, type FormSubmitData, type FormSubmitResponse, type FunnelStepData, type GlobalBlock, type GlobalBlockResponse, type LegalDocument, type LynkowClient, type LynkowConfig, LynkowError, type LynkowEvents, type Page, type PageSeo, type PageSummary, type PagesListResponse, type PageviewData, type PaginatedResponse, type PaginationMeta, type PaginationOptions, type Path, type PathsListResponse, type Redirect, type ResolveResponse, type Review, type ReviewResponse, type ReviewSettings, type ReviewSubmitData, type ReviewSubmitResponse, type ReviewsFilters, type ReviewsListResponse, type SiteConfig, type SiteConfigResponse, type SortOptions, type SubmitOptions, type Tag, type TagsListResponse, type TipTapMark, type TipTapNode, browserOnly, browserOnlyAsync, createClient, createLynkowClient, isBrowser, isCategoryResolve, isContentResolve, isLynkowError, isServer };
2330
+ export { type Alternate, type ApiErrorDetail, type Author, type BaseRequestOptions, type CategoriesListResponse, type Category, type CategoryDetail, type CategoryDetailResponse, type CategoryOptions, type CategoryResolveResponse, type CategoryTreeNode, type CategoryTreeResponse, type CategoryWithCount, type Client, type ClientConfig, type ConsentCategories, type ConsentLogResponse, type Content, type ContentBody, type ContentResolveResponse, type ContentSummary, type ContentsFilters, type ContentsListResponse, type CookieCategory, type CookieConfig, type CookiePreferences, type CookieTexts, EnhancementsService, type ErrorCode, type EventData, type EventName, type Form, type FormField, type FormFieldOption, type FormFieldType, type FormFieldValidation, type FormSettings, type FormSubmitData, type FormSubmitResponse, type FunnelStepData, type GlobalBlock, type GlobalBlockResponse, type ImageVariants, type LegalDocument, type LynkowClient, type LynkowConfig, LynkowError, type LynkowEvents, MediaHelperService, type Page, type PageSeo, type PageSummary, type PagesListResponse, type PageviewData, type PaginatedResponse, type PaginationMeta, type PaginationOptions, type Path, type PathsListResponse, type Redirect, type ResolveResponse, type Review, type ReviewResponse, type ReviewSettings, type ReviewSubmitData, type ReviewSubmitResponse, type ReviewsFilters, type ReviewsListResponse, type SiteConfig, type SiteConfigResponse, type SortOptions, type SrcsetOptions, type SubmitOptions, type Tag, type TagsListResponse, type TipTapMark, type TipTapNode, type TransformOptions, browserOnly, browserOnlyAsync, createClient, createLynkowClient, isBrowser, isCategoryResolve, isContentResolve, isLynkowError, isServer };