npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@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-types

Main Exports

  • raw catalogs such as themeNames, layoutVariants, pageStatuses, buildStatuses, deploymentProviders, widgetTypes, and textFormats
  • enums for themes, layout variants, page status, build status, deployment provider, widget type, and text format
  • separate stored and resolved media reference schemas
  • widgetSchema for storage and resolvedWidgetSchema for build artifacts
  • composed and frontend-ready Landing Page data schemas
  • buildSchema, buildManifestSchema, and globalManifestSchema

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:

  • MediaImageRef is the persisted/admin shape. It stores stable Media Library identity (project, mediaId, preset) plus editorial rendering hints such as alt, loading, and priority.
  • ResolvedMediaImageRef is 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, and format.

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:

  1. Admin, presets, and custom widget configs save MediaImageRef.
  2. sls-lp build reads each widget and calls Media Library using project and mediaId.
  3. The build verifies that the media belongs to the expected project, is READY, and contains a variant for preset.
  4. The selected variant, preferably webp when available, is copied back onto the original reference as src, width, height, and format.
  5. 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:home
  • mui:shield-outlined
  • fa:house
  • custom:my-icon

Invalid examples:

  • home
  • key
  • mui
  • :home
  • mui:
  • 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,
      },
    ],
  },
})