// Wire types of GET /_seo/api/v1/resolve. Field names mirror the Go // serializer (classes.Result in sm-seo-plugin) exactly. Types only, so // `node --test` can import any util. /** ok, not_found, redirect or gone. */ export type SeoAction = 'ok' | 'not_found' | 'redirect' | 'gone' export interface SeoMetaTag { name: string content: string } /** The head metadata of a resolved page. Empty strings mean "no value". */ export interface SeoHead { title: string description: string canonical: string robots: string x_robots_tag: string og: { title: string description: string image: string url: string /** og:locale of the page (pl_PL); absent from backends before SEO v0.2.0. */ locale?: string /** og:locale:alternate values, one per other translated locale. */ locale_alternates?: string[] } twitter: { card: string; site: string } verification: SeoMetaTag[] } export interface SeoResolveAnswer { action: SeoAction /** The HTTP status the frontend should answer with (200, 301, 302, 404, 410). */ status: number /** The absolute target of a redirect answer; absent otherwise. */ location?: string /** The absolute URL of the page on the site URL. */ url: string locale: string /** True outside the backend's production environment: noindex everywhere. */ staging: boolean /** Set on ok answers only. */ seo: SeoHead | null // The keys below are additive (SEO plugin v0.2.0); an older backend leaves // them out and every consumer treats an absent key as empty. /** The value (pl, pl-PL), set on ok answers. */ html_lang?: string /** hreflang alternates including the page itself and x-default; absolute URLs. */ alternates?: SeoAlternate[] /** One {"@context", "@graph"} object, or null. */ jsonld?: SeoJsonLd | null breadcrumbs?: SeoBreadcrumb[] /** Present only when the request carries a page number. */ pagination?: SeoPaginationAnswer outbound?: SeoOutbound autolinks?: Array<{ phrase: string; url: string }> autolink_max?: number } export interface SeoAlternate { hreflang: string url: string } /** A schema.org node; @id links nodes across the graph. */ export type SeoSchemaNode = Record & { '@id'?: string; '@type'?: string | string[] } export interface SeoJsonLd { '@context'?: string '@graph'?: SeoSchemaNode[] } export interface SeoBreadcrumb { name: string url: string path: string } export interface SeoPaginationAnswer { form?: 'query' | 'path' param?: string segment?: string page?: number /** A page value that is not a page number (?page=abc): the layer answers 404. */ invalid?: boolean } export interface SeoOutbound { new_tab?: boolean nofollow_domains?: string[] sponsored_domains?: string[] } /** GET /_seo/api/v1/site. Every key may be absent on an older backend. */ export interface SeoSiteAnswer { site_url?: string default_locale?: string locales?: string[] unprefixed_locale?: string links?: { new_tab?: boolean } html_sitemap?: { enabled?: boolean; paths?: Record; page_size?: number } routes?: Array<{ type: string; pattern: string }> /** Root file names the backend serves (verification files, the IndexNow key file). */ root_files?: string[] llms?: boolean pagination?: { form?: 'query' | 'path'; param?: string; segments?: Record } home_crumb?: { name?: string; url?: string } | null }