Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | 10x 10x 10x 10x | /**
* ProfessionalService JSON-LD for a city hub (#1118). One node per hub at
* `{hub}#service`, linked to the homepage Organization through
* `parentOrganization`. Address and phone are always the company's — never
* a local office.
*/
import { BRAND, BRAND_POSTAL_ADDRESS } from "../content/brand";
import { wikidataSameAs } from "./live-city";
export type CityServiceSchemaInput = {
siteUrl: string;
slug: string;
publicName: string;
wikidataId: string | null | undefined;
pricesApproved: boolean;
description: string;
aggregateRating?: Record<string, unknown> | null;
dateModified?: string;
};
export function cityServiceSchema(
input: CityServiceSchemaInput,
): Record<string, unknown> {
const origin = input.siteUrl.replace(/\/$/, "");
const hubUrl = `${origin}/interiors/${input.slug}`;
const sameAs = wikidataSameAs(input.wikidataId);
return {
"@context": "https://schema.org",
"@type": "ProfessionalService",
"@id": `${hubUrl}#service`,
name: `Interioring — Interior Designers in ${input.publicName}`,
url: hubUrl,
parentOrganization: { "@id": `${origin}#organization` },
address: BRAND_POSTAL_ADDRESS,
telephone: BRAND.phone,
areaServed: {
"@type": "City",
name: input.publicName,
...(sameAs ? { sameAs } : {}),
},
...(input.pricesApproved ? { priceRange: "₹₹₹" } : {}),
description: input.description,
dateModified: input.dateModified ?? new Date().toISOString(),
...(input.aggregateRating
? { aggregateRating: input.aggregateRating }
: {}),
};
}
|