@verisure-italy/lp-types
v3.0.2
Published
Types for Landing Page service
Readme
@verisure-italy/lp-types
Domain contracts for landing pages, widgets, presets, SEO metadata, and build manifests.
Version 3 migration: MIGRATION-3.0.md.
Installation
pnpm add @verisure-italy/lp-typesMain Exports
- raw catalogs such as
themeNames,layoutVariants,pageStatuses,buildStatuses,deploymentProviders,widgetTypes, andtextFormats - enums for themes, layout variants, page status, build status, deployment provider, widget type, and text format
- separate stored and resolved media reference schemas
widgetSchemafor storage andresolvedWidgetSchemafor build artifacts- composed and frontend-ready Landing Page data schemas
buildSchema,buildManifestSchema, andglobalManifestSchema
What This Package Gives You
- an authoring model for landing pages and widget presets
- a runtime-safe discriminated union for widget rendering
- build and deployment metadata for page publishing flows
- reusable text, media-image reference, and navigation primitives for page composition
Schema Inventory
| Schema | Type alias | Kind | Purpose |
| --------------------------------------- | --------------------------------- | ---------------------- | --------------------------------------------- |
| mediaImageRefSchema | MediaImageRef | object schema | Stored media-library reference |
| resolvedMediaImageRefSchema | ResolvedMediaImageRef | object schema | Resolved artifact image |
| responsiveMediaImageRefSchema | ResponsiveMediaImageRef | object schema | Stored desktop/mobile references |
| resolvedResponsiveMediaImageRefSchema | ResolvedResponsiveMediaImageRef | object schema | Resolved desktop/mobile outputs |
| mediaVariantPresetNameSchema | MediaVariantPresetName | enum | Re-export from Media Library types |
| generatedFormatSchema | GeneratedFormat | enum | Re-export from Media Library types |
| mediaImageLoadingSchema | MediaImageLoading | enum | Image loading hint |
| themeNameSchema | ThemeName | enum | Page theme |
| layoutVariantSchema | LayoutVariant | enum | Layout variant |
| pageStatusSchema | PageStatus | enum | Publication status |
| buildStatusSchema | BuildStatus | enum | Build status |
| seoMetadataSchema | SeoMetadata | object schema | SEO metadata |
| deploymentProviderSchema | DeploymentProvider | enum | Deployment provider |
| widgetAlignmentSchema | WidgetAlignment | enum | Widget alignment values |
| widgetIconTokenSchema | WidgetIconToken | string schema | Namespaced icon token (provider:name) |
| widgetIconSchema | n/a | nullable string schema | Nullable namespaced icon token |
| widgetTypeSchema | WidgetType | enum | Widget discriminator |
| widgetContentListSubTypeSchema | WidgetContentListSubType | enum | Content-list variants |
| widgetStaticContentSubTypeSchema | WidgetStaticContentSubType | enum | StaticContent variants |
| widgetCostsItemVisibilitySchema | WidgetCostsItemVisibility | enum | Costs-item visibility |
| textFormatSchema | TextFormat | enum | Text formatting mode |
| textContentSchema | TextContent | union | Rich text primitive |
| widgetCtaSchema | WidgetCta | object schema | Reusable CTA with label and optional link |
| widgetAnchorIdSchema | WidgetAnchorId | string schema | DOM anchor id without # |
| pageFunnelPathIdSchema | PageFunnelPathId | UUID schema | Funnel path id linked to a page |
| widgetHeroSchema | WidgetHero | object schema | Hero widget |
| widgetProductSliderSchema | WidgetProductSlider | object schema | Product-slider widget |
| widgetCostsSchema | WidgetCosts | object schema | Costs widget |
| widgetContentBoxSchema | WidgetContentBox | object schema | Content-box widget |
| widgetTrustpilotSchema | WidgetTrustpilot | object schema | Trustpilot widget |
| widgetFAQSchema | WidgetFAQ | object schema | FAQ widget |
| widgetStatsSchema | WidgetStats | object schema | Stats widget |
| widgetContentListSchema | WidgetContentList | object schema | Content-list widget |
| widgetStaticContentSchema | WidgetStaticContent | object schema | StaticContent widget |
| widgetFunnelSwitcherSchema | WidgetFunnelSwitcher | object schema | Funnel-switcher widget |
| widgetPropertyTypeSchema | WidgetPropertyType | object schema | Property-type widget |
| widgetAlarmTypeComparisonSchema | WidgetAlarmTypeComparison | object schema | Alarm-comparison widget |
| widgetHeaderMenuLinkSchema | WidgetHeaderMenuLink | discriminated union | Header menu links |
| widgetHeaderSchema | WidgetHeader | object schema | Header widget |
| widgetFooterMenuItemSchema | WidgetFooterMenuItem | object schema | Footer menu item |
| widgetFooterMenuSectionSchema | WidgetFooterMenuSection | object schema | Footer menu section |
| widgetFooterSchema | WidgetFooter | object schema | Footer widget |
| widgetSchema | Widget | discriminated union | Full widget union |
| resolvedWidgetSchema | ResolvedWidget | discriminated union | Widget union with resolved media |
| widgetPresetSchema | WidgetPreset | object schema | Stored widget preset |
| pageWidgetConfigSchema | PageWidgetConfig | discriminated union | Stored page widget config |
| pageSchema | Page | object schema | Persisted page |
| buildManifestPageSchema | BuildManifestPage | object schema | Compact page in build artifacts |
| buildManifestSchema | BuildManifest | object schema | Build manifest |
| globalManifestSchema | GlobalManifest | object schema | Current, previous, and pending manifests |
| landingPageFunnelSummarySchema | LandingPageFunnelSummary | object schema | Static funnel summary in page payloads |
| landingPageFunnelPathDataSchema | LandingPageFunnelPathData | object schema | Static funnel path data in page payloads |
| composedLandingPageWidgetConfigSchema | ComposedLandingPageWidgetConfig | discriminated union | Composed config before media resolution |
| resolvedLandingPageWidgetConfigSchema | ResolvedLandingPageWidgetConfig | discriminated union | Widget config with resolved widget payload |
| composedLandingPageDataSchema | ComposedLandingPageData | object schema | Composed page before media resolution |
| landingPageDataSchema | LandingPageData | object schema | Frontend-ready page payload |
| buildSchema | Build | object schema | Build execution record |
Enum Reference
| Schema | Values |
| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| themeNameSchema | standard, dark |
| layoutVariantSchema | default, marketing |
| pageStatusSchema | draft, published, needs_republish |
| buildStatusSchema | pending, building, completed, failed |
| deploymentProviderSchema | amplify, apprunner, ecs |
| mediaVariantPresetNameSchema | Canonical names from @verisure-italy/media-library-types |
| generatedFormatSchema | webp, jpeg, avif |
| mediaImageLoadingSchema | lazy, eager |
| widgetAlignmentSchema | left, center, right |
| widgetIconTokenSchema | string matching ^[a-z0-9][a-z0-9-]*:[a-z0-9][a-z0-9-]*$ |
| widgetTypeSchema | hero, productSlider, costs, contentBox, trustpilot, faq, stats, contentList, staticContent, funnelSwitcher, propertyType, alarmTypeComparison, header, footer |
| widgetContentListSubTypeSchema | keyStrengths, howItWorks |
| widgetStaticContentSubTypeSchema | fingerSwipe, columnContent, trustpilot, shieldRedBanner |
| widgetCostsItemVisibilitySchema | desktop, mobile |
| textFormatSchema | plain, markdown |
Primitive Schema Reference
Image Contract
Stored LP widget payloads contain only Media Library identity and editorial hints. Build artifacts use separate resolved schemas with authoritative URL, actual dimensions, and generated format. Stored records reject resolved fields. Artifact schemas reject unresolved references.
This split is intentional:
MediaImageRefis the persisted/admin shape. It stores stable Media Library identity (project,mediaId,preset) plus editorial rendering hints such asalt,loading, andpriority.ResolvedMediaImageRefis the static build artifact shape. It keeps the same identity and editorial fields, then adds the generated output selected by the build:src,width,height, andformat.
Keeping both contracts prevents persisted widget presets from storing derived CDN
data that can change when Media Library reprocesses an asset, changes a CDN host,
or regenerates variants. It also lets build artifacts be strict frontend-ready
payloads: consumers render src exactly as written and do not need to know how to
query Media Library.
The lifecycle is:
- Admin, presets, and custom widget configs save
MediaImageRef. sls-lpbuild reads each widget and calls Media Library usingprojectandmediaId.- The build verifies that the media belongs to the expected
project, isREADY, and contains a variant forpreset. - The selected variant, preferably
webpwhen available, is copied back onto the original reference assrc,width,height, andformat. - The page artifact is validated as
ResolvedWidget/landingPageDataSchema.
In other words, ResolvedMediaImageRef is MediaImageRef after build-time Media
Library resolution. It is not a separate editable source of truth.
mediaImageRefSchema
| Field | Type | Required | Notes |
| ---------- | ------------------------ | -------- | --------------------------------- |
| mediaId | string | Yes | Media-library asset id |
| project | string | Yes | Media-library project namespace |
| preset | MediaVariantPresetName | Yes | Canonical Media Library preset |
| alt | string | No | Contextual/editorial alt override |
| loading | 'lazy' \| 'eager' | No | Render-position loading hint |
| priority | boolean | No | Render-position priority hint |
src, width, height, and format are rejected by this strict storage schema.
resolvedMediaImageRefSchema
Extends stored reference fields with:
| Field | Type | Required | Notes |
| -------- | ----------------- | -------- | ----------------------------------- |
| src | string URL | Yes | Authoritative source-versioned URL |
| width | positive integer | Yes | Actual generated width |
| height | positive integer | Yes | Actual generated height |
| format | GeneratedFormat | Yes | Generated webp, jpeg, or avif |
Consumers must use src exactly. No URL reconstruction or generic srcSet is part
of this contract.
responsiveMediaImageRefSchema
| Field | Type | Required | Notes |
| ---------- | ----------------------- | -------- | ------------------------------- |
| desktop | MediaImageRef | Yes | Desktop media reference |
| mobile | MediaImageRef \| null | No | Optional mobile media reference |
| alt | string | No | Responsive-level alt override |
| loading | 'lazy' \| 'eager' | No | Responsive-level loading hint |
| priority | boolean | No | Responsive-level priority hint |
resolvedResponsiveMediaImageRefSchema
Same responsive envelope, but desktop and optional mobile use
ResolvedMediaImageRef. Each output keeps its own URL and actual dimensions.
widgetIconTokenSchema and widgetIconSchema
| Rule | Value |
| ----------------------- | ----------------------------------------- |
| Token format | provider:name |
| Regex | ^[a-z0-9][a-z0-9-]*:[a-z0-9][a-z0-9-]*$ |
| widgetIconTokenSchema | Required namespaced token |
| widgetIconSchema | Same token, but nullable |
Valid examples:
mui:homemui:shield-outlinedfa:housecustom:my-icon
Invalid examples:
homekeymui:homemui:MUI:home
widgetAnchorIdSchema
| Rule | Value |
| ---------- | -------------------------------------------------------------- |
| Type | string |
| Required | Yes |
| Validation | Must match ^[a-z0-9-]+$ and does not include the leading # |
pageFunnelPathIdSchema
| Rule | Value |
| ---------- | -------------- |
| Type | string |
| Required | Yes |
| Validation | Must be a UUID |
textContentSchema
| Variant | Shape | Notes |
| ------------------ | --------------------------------------- | ------------------------- |
| Plain string | string | Must be non-empty |
| Structured content | { value: string; format: TextFormat } | value must be non-empty |
seoMetadataSchema
| Field | Type | Required | Notes |
| -------------------- | ---------- | -------- | ----------------- |
| title | string | Yes | Min 1, max 60 |
| description | string | Yes | Min 1, max 160 |
| keywords | string[] | Yes | Keyword list |
| canonicalUrl | string | No | Valid URL |
| ogImage | string | No | Valid URL |
| ogTitle | string | No | Optional override |
| ogDescription | string | No | Optional override |
| robots | string | No | Robots directive |
| languageAlternates | array | No | { lang, url }[] |
Page and Build Schemas
widgetPresetSchema
| Field | Type | Required | Notes |
| ----------- | ---------- | -------- | ---------------- |
| id | string | Yes | Preset id |
| name | string | Yes | Preset name |
| tags | string[] | Yes | Tag list |
| widget | Widget | Yes | Widget payload |
| createdAt | number | Yes | Shared timestamp |
| updatedAt | number | Yes | Shared timestamp |
pageWidgetConfigSchema
Common fields:
| Field | Type | Required | Notes |
| ------------ | ---------------------- | -------- | ------------------------- |
| id | string | Yes | Config id |
| pageId | string | Yes | Page id |
| configType | 'preset' \| 'custom' | Yes | Variant discriminator |
| order | number | Yes | Non-negative integer |
| anchorId | string \| null | No | Optional widget anchor id |
| createdAt | number | Yes | Shared timestamp |
| updatedAt | number | Yes | Shared timestamp |
Variant-specific fields:
| Variant | Additional fields |
| -------- | ------------------ |
| preset | presetId: string |
| custom | widget: Widget |
pageSchema
| Field | Type | Required | Notes |
| ----------------- | -------------------- | ------------ | -------------------------- |
| id | string | Yes | Page id |
| slug | string | Yes | Must match ^[a-z0-9-]+$ |
| name | string | Yes | Non-empty |
| description | string | No | Optional |
| funnelPathId | string | Yes | Required Funnel Path UUID |
| widgets | PageWidgetConfig[] | Yes | Widget config list |
| theme | ThemeName | Yes | Theme enum |
| layoutVariant | LayoutVariant | No (default) | Defaults to default |
| seo | SeoMetadata | Yes | SEO metadata |
| status | PageStatus | Yes | Publication state |
| requiresRebuild | boolean | Yes | Build flag |
| version | number | Yes | Positive integer |
| publishedAt | number | No | Optional publish timestamp |
| createdAt | number | Yes | Shared timestamp |
| updatedAt | number | Yes | Shared timestamp |
buildManifestPageSchema
| Field | Type | Required | Notes |
| --------------- | --------------- | ------------ | --------------------- |
| id | string | Yes | Page id |
| slug | string | Yes | Page slug |
| name | string | Yes | Page name |
| theme | ThemeName | Yes | Page theme |
| layoutVariant | LayoutVariant | No (default) | Defaults to default |
buildManifestSchema
| Field | Type | Required | Notes |
| ------------ | --------------------- | -------- | -------------------- |
| buildId | string | Yes | Build id |
| createdAt | string | Yes | ISO timestamp |
| pagesCount | number | Yes | Non-negative integer |
| pages | BuildManifestPage[] | Yes | Included pages |
globalManifestSchema
| Field | Type | Required | Notes |
| ---------- | ----------------------- | -------------- | ------------------------- |
| current | BuildManifest \| null | Yes (nullable) | Current deployment |
| previous | BuildManifest \| null | Yes (nullable) | Previous deployment |
| new | BuildManifest \| null | Yes (nullable) | Pending or new deployment |
composedLandingPageWidgetConfigSchema
Same base fields as pageWidgetConfigSchema, but both variants include an unresolved
Widget after preset/custom composition and before Media Library resolution.
resolvedLandingPageWidgetConfigSchema
Same base fields, but both variants include a ResolvedWidget payload:
| Variant | Additional fields |
| -------- | -------------------- |
| preset | presetId, widget |
| custom | widget |
landingPageDataSchema
landingPageDataSchema is pageSchema with widgets replaced by
ResolvedLandingPageWidgetConfig[]. Every image must include src, width, height,
and format.
composedLandingPageDataSchema represents the prior build step and accepts unresolved
widgets. Both schemas require static funnelPath data.
landingPageFunnelPathDataSchema
| Field | Type | Required | Notes |
| ---------------------- | ---------------- | -------------- | ----------------------------------------- |
| path | string | Yes | Must match ^[a-z0-9-]+$ |
| titleHeader | string \| null | Yes (nullable) | Optional header title from Funnel Path |
| titleSubHeader | string \| null | Yes (nullable) | Optional header subtitle from Funnel Path |
| titleIntroduction | string | Yes | Introduction title |
| subTitleIntroduction | string | Yes | Introduction subtitle |
| funnels | array | Yes | Static funnel list, at least one item |
Each funnels item contains title, slug, and type.
buildSchema
| Field | Type | Required | Notes |
| -------------------- | ---------------------------- | -------------- | --------------------- |
| id | string | Yes | Build id |
| status | BuildStatus | Yes | Build state |
| deploymentProvider | DeploymentProvider \| null | No | Deployment backend |
| deploymentId | string \| null | No | Provider-specific id |
| deploymentRef | string \| null | No | Provider-specific ref |
| deploymentTarget | string \| null | No | Deployment target |
| deploymentStatus | string \| null | No | Provider status |
| amplifyBuildId | string \| null | No | Deprecated field |
| amplifyJobUrl | string \| null | No | Deprecated field |
| startedAt | number \| null | Yes (nullable) | Start timestamp |
| completedAt | number \| null | No | Completion timestamp |
| duration | number \| null | No | Duration |
| pagesCount | number \| null | Yes (nullable) | Number of pages |
| pageIds | string[] | Yes | Included page ids |
| error | string \| null | No | Error message |
| s3BucketPath | string \| null | Yes (nullable) | Artifact path |
| createdAt | number | Yes | Shared timestamp |
| updatedAt | number | Yes | Shared timestamp |
Widget Schemas
widgetSchema
Each widget is exported through widgetSchema with a type discriminator and a properties object.
| type value | properties schema |
| --------------------- | --------------------------------- |
| hero | widgetHeroSchema |
| productSlider | widgetProductSliderSchema |
| costs | widgetCostsSchema |
| contentBox | widgetContentBoxSchema |
| trustpilot | widgetTrustpilotSchema |
| faq | widgetFAQSchema |
| stats | widgetStatsSchema |
| contentList | widgetContentListSchema |
| staticContent | widgetStaticContentSchema |
| funnelSwitcher | widgetFunnelSwitcherSchema |
| propertyType | widgetPropertyTypeSchema |
| alarmTypeComparison | widgetAlarmTypeComparisonSchema |
| header | widgetHeaderSchema |
| footer | widgetFooterSchema |
widgetHeroSchema
| Field | Type | Required | Notes |
| ---------------- | --------------------------- | -------- | ------------------------------------------------------------------------------ |
| title | TextContent | Yes | String or { value, format } |
| subtitle | TextContent \| null | No | Optional |
| body | TextContent \| null | No | Optional |
| primaryOffer | TextContent \| null | No | Optional |
| secondaryOffer | TextContent \| null | No | Optional |
| cta | object or null | No | Contains label; legacy funnelPath and funnelSlug are optional/deprecated |
| media | ResponsiveMediaImageRef[] | Yes | At least one responsive image reference |
widgetProductSliderSchema
| Field | Type | Required | Notes |
| ------------- | --------------------- | -------------- | ----------------------------------------------------------------------------- |
| title | TextContent | Yes | Title |
| description | TextContent \| null | Yes (nullable) | Description block |
| items | array | Yes | Each item contains image: MediaImageRef, title, description, featured |
widgetCostsSchema
| Field | Type | Required | Notes |
| ------------- | --------------------- | -------------- | --------------------------------------------------------------------------------------------- |
| title | TextContent | Yes | Title |
| subtitle | TextContent \| null | Yes (nullable) | Subtitle |
| description | TextContent \| null | Yes (nullable) | Description |
| items | array | Yes | Each item contains title, description, icon (provider:name or null), visibility[] |
widgetContentBoxSchema
| Field | Type | Required | Notes |
| ------------- | --------------------- | -------------- | --------------------------------------------------------------------------------------------- |
| title | TextContent \| null | Yes (nullable) | Section title |
| description | TextContent \| null | Yes (nullable) | Description |
| box | object | Yes | Contains title, description, image: ResponsiveMediaImageRef \| null, alignment, cta |
| box.cta | WidgetCta \| null | Yes (nullable) | Contains label and optional link |
widgetTrustpilotSchema
| Field | Type | Required | Notes |
| ----------------------- | --------------------- | -------------- | ----------- |
| title | TextContent | Yes | Title |
| description | TextContent \| null | Yes (nullable) | Description |
| config.businessUnitId | string | Yes | Non-empty |
| config.templateId | string | Yes | Non-empty |
| config.styleHeight | string | Yes | Non-empty |
| config.styleWidth | string | Yes | Non-empty |
| config.locale | string | Yes | Non-empty |
widgetFAQSchema
| Field | Type | Required | Notes |
| ------------- | --------------------- | -------------- | ------------------------------------------ |
| title | TextContent | Yes | Title |
| description | TextContent \| null | Yes (nullable) | Description |
| items | array | Yes | Each item contains question and answer |
widgetStatsSchema
| Field | Type | Required | Notes |
| ------- | ----- | -------- | ------------------------------------------------------------------------------------ |
| items | array | Yes | Each item contains label, value, and optional icon (provider:name or null) |
widgetContentListSchema
| Field | Type | Required | Notes |
| ------------- | --------------------- | -------------- | --------------------------------------------------------------------------------------- |
| subType | enum | Yes | keyStrengths or howItWorks |
| title | TextContent | Yes | Title |
| description | TextContent \| null | Yes (nullable) | Description |
| items | array | Yes | Each item contains title, description, and image: ResponsiveMediaImageRef \| null |
widgetStaticContentSchema
StaticContent widgets are declarative selectors for frontend-rendered static blocks. They carry no HTML and no dynamic content.
| Field | Type | Required | Notes |
| --------- | ---- | -------- | ------------------------------------------------------------------ |
| subType | enum | Yes | fingerSwipe, columnContent, trustpilot, or shieldRedBanner |
widgetFunnelSwitcherSchema
| Field | Type | Required | Notes |
| ------------- | --------------------- | -------------- | ----------- |
| title | TextContent | Yes | Title |
| subtitle | TextContent \| null | Yes (nullable) | Subtitle |
| description | TextContent \| null | Yes (nullable) | Description |
Funnel-switcher cards are derived by consumers from page-level funnelPath.funnels.
Each card should link to /allarme/<funnelPath.path>/<funnel.slug> and use
funnel.type for frontend asset selection. Legacy items are optional/deprecated.
widgetPropertyTypeSchema
| Field | Type | Required | Notes |
| ------------- | --------------------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| title | TextContent | Yes | Title |
| description | TextContent \| null | Yes (nullable) | Description |
| tabs | array | Yes | Each tab contains optional label, title, description, image: ResponsiveMediaImageRef \| null, and cta.label; legacy cta.link is optional/deprecated |
widgetAlarmTypeComparisonSchema
| Field | Type | Required | Notes |
| ------------- | --------------------- | -------------- | ------------------------------------------------------------------------------------------------------------ |
| title | TextContent | Yes | Title |
| description | TextContent \| null | Yes (nullable) | Description |
| tabs | array | Yes | Each tab contains title, description, image: MediaImageRef \| null, icon (provider:name or null) |
| box | object | Yes | Contains title, description, icon (provider:name or null) |
Icon Migration Notes (Breaking)
Legacy non-namespaced icon values are no longer valid.
| Old value | New value |
| ---------- | ----------------- |
| home | mui:home |
| key | mui:key |
| operator | custom:operator |
If an icon is not provided, keep using null where the field is nullable.
Example payload update:
// before (invalid from v2)
{
icon: 'home'
}
// after
{
icon: 'mui:home'
}widgetHeaderMenuLinkSchema
| Variant | Fields |
| -------------- | ----------------------------------------------------------- |
| anchor | label, anchor where anchor must match ^#[a-z0-9-]+$ |
| external | label, url |
| widgetAnchor | label, targetWidgetConfigId |
widgetHeaderSchema
| Field | Type | Required | Notes |
| ---------- | ---------------- | -------- | ----------------------------------------- |
| logo | MediaImageRef | Yes | Logo media reference |
| logoLink | string \| null | No | Optional URL |
| menu | object or null | No | Contains enabled and optional items[] |
widgetFooterMenuItemSchema
| Field | Type | Required | Notes |
| ------- | ------------- | -------- | --------------- |
| label | TextContent | Yes | Menu item label |
| url | string | Yes | Valid URL |
widgetFooterMenuSectionSchema
| Field | Type | Required | Notes |
| ------- | ------------------------ | -------- | ----------------- |
| title | TextContent | Yes | Section title |
| items | WidgetFooterMenuItem[] | Yes | At least one link |
widgetFooterSchema
| Field | Type | Required | Notes |
| --------------------- | ----------------------- | -------- | ------------------------------------------- |
| paragraphs | TextContent[] \| null | No | Optional |
| menuSections | array or null | No | Each section contains title and items[] |
| phone | TextContent \| null | No | Optional |
| address | TextContent \| null | No | Optional |
| copyright | TextContent \| null | No | Optional |
| customerServiceLink | object or null | No | Contains label and url |
Example
import { widgetSchema } from '@verisure-italy/lp-types'
const hero = widgetSchema.parse({
type: 'hero',
properties: {
title: 'Protect your home',
media: [
{
desktop: {
mediaId: 'media-hero-desktop',
project: 'sls-lp',
preset: 'funnel-hero-desktop',
alt: 'Alarm system',
},
mobile: {
mediaId: 'media-hero-mobile',
project: 'sls-lp',
preset: 'funnel-hero-mobile',
alt: 'Alarm system',
},
loading: 'eager',
priority: true,
},
],
},
})