- Per-page titles, descriptions, canonicals, Open Graph/Twitter tags via a shared pageMetadata() helper; metadataBase on the root layout - Sitemap generated from a route list on the canonical non-www host; robots.txt points to it; /services removed - One H1 per page; decorative images get empty alt text - JSON-LD: site-wide ComputerRepairService, FAQPage on the homepage, Service on each service page - FAQ answers are now server-rendered (forceMount) so the schema matches the HTML; fixed the nested payment FAQ item - Drop web design (page, nav link, homepage card and FAQs); 301 the old URL - Remove GA, Facebook Pixel and Vercel Analytics/Speed Insights - Fix tel: links (+640211... -> +64211...) - Add og-image.png and logo.png Co-Authored-By: Claude Opus 5.5 <[email protected]>
155 lines
4.1 KiB
JavaScript
155 lines
4.1 KiB
JavaScript
// Single source of truth for business facts (from the owner inputs in PLAN.md).
|
||
// Update values here rather than hard-coding them in pages.
|
||
|
||
export const SITE_URL = "https://teatatucomputers.com";
|
||
|
||
export const business = {
|
||
name: "Te Atatu Computers",
|
||
ownerName: "John",
|
||
phone: "021 107 7483",
|
||
phoneE164: "+64211077483",
|
||
email: "[email protected]",
|
||
address: {
|
||
street: "34 Graham Avenue",
|
||
suburb: "Te Atatū Peninsula",
|
||
city: "Auckland",
|
||
postcode: "0610",
|
||
country: "NZ",
|
||
},
|
||
hours: "Mon–Fri 9am–6pm. Weekends by appointment.",
|
||
serviceArea: [
|
||
"Te Atatū Peninsula",
|
||
"Te Atatū South",
|
||
"Henderson",
|
||
"Massey",
|
||
"Lincoln",
|
||
"Glendene",
|
||
"Westgate",
|
||
"Auckland CBD",
|
||
],
|
||
paymentMethods: [
|
||
"Cash",
|
||
"NZ bank transfer",
|
||
"Contactless Visa, Mastercard and American Express",
|
||
"Apple Pay, Google Pay and Samsung Pay",
|
||
"Bitcoin",
|
||
],
|
||
googleBusinessProfileUrl: "https://share.google/APzXLRzyrqAUldl4Y",
|
||
googleReviewUrl: "https://g.page/r/CYkJobPXq4IpEAE/review",
|
||
facebookUrl: "https://www.facebook.com/profile.php?id=61571509018351",
|
||
};
|
||
|
||
export const BUSINESS_ID = `${SITE_URL}/#business`;
|
||
|
||
// Every public route. Used by the sitemap; add new pages here.
|
||
export const routes = [
|
||
{ path: "/", priority: 1 },
|
||
{ path: "/services/computer-repair", priority: 0.8 },
|
||
{ path: "/services/computer-upgrades", priority: 0.8 },
|
||
{ path: "/services/virus-removal", priority: 0.8 },
|
||
{ path: "/services/it-support", priority: 0.8 },
|
||
{ path: "/contact", priority: 0.6 },
|
||
];
|
||
|
||
// Builds per-page metadata: title, description, canonical, Open Graph and Twitter.
|
||
export function pageMetadata({ title, description, path }) {
|
||
return {
|
||
title,
|
||
description,
|
||
alternates: { canonical: path },
|
||
openGraph: {
|
||
title,
|
||
description,
|
||
url: path,
|
||
siteName: business.name,
|
||
locale: "en_NZ",
|
||
type: "website",
|
||
images: [
|
||
{
|
||
url: "/og-image.png",
|
||
width: 1200,
|
||
height: 630,
|
||
alt: business.name,
|
||
},
|
||
],
|
||
},
|
||
twitter: {
|
||
card: "summary_large_image",
|
||
title,
|
||
description,
|
||
images: ["/og-image.png"],
|
||
},
|
||
};
|
||
}
|
||
|
||
export function localBusinessSchema() {
|
||
const { address } = business;
|
||
return {
|
||
"@context": "https://schema.org",
|
||
"@type": "ComputerRepairService",
|
||
"@id": BUSINESS_ID,
|
||
name: business.name,
|
||
url: `${SITE_URL}/`,
|
||
telephone: business.phoneE164,
|
||
email: business.email,
|
||
logo: `${SITE_URL}/logo.png`,
|
||
image: `${SITE_URL}/og-image.png`,
|
||
address: {
|
||
"@type": "PostalAddress",
|
||
streetAddress: address.street,
|
||
addressLocality: address.suburb,
|
||
addressRegion: address.city,
|
||
postalCode: address.postcode,
|
||
addressCountry: address.country,
|
||
},
|
||
areaServed: business.serviceArea.map((name) => ({
|
||
"@type": "Place",
|
||
name: `${name}, Auckland`,
|
||
})),
|
||
openingHoursSpecification: [
|
||
{
|
||
"@type": "OpeningHoursSpecification",
|
||
dayOfWeek: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
|
||
opens: "09:00",
|
||
closes: "18:00",
|
||
},
|
||
],
|
||
priceRange: "$",
|
||
currenciesAccepted: "NZD",
|
||
paymentAccepted: business.paymentMethods.join(", "),
|
||
hasMap: business.googleBusinessProfileUrl,
|
||
sameAs: [business.googleBusinessProfileUrl, business.facebookUrl],
|
||
};
|
||
}
|
||
|
||
export function serviceSchema({ name, description, path }) {
|
||
return {
|
||
"@context": "https://schema.org",
|
||
"@type": "Service",
|
||
name,
|
||
serviceType: name,
|
||
description,
|
||
url: `${SITE_URL}${path}`,
|
||
provider: { "@id": BUSINESS_ID },
|
||
areaServed: business.serviceArea.map((area) => ({
|
||
"@type": "Place",
|
||
name: `${area}, Auckland`,
|
||
})),
|
||
};
|
||
}
|
||
|
||
export function faqSchema(faqs) {
|
||
return {
|
||
"@context": "https://schema.org",
|
||
"@type": "FAQPage",
|
||
mainEntity: faqs.map(({ question, answer, list }) => ({
|
||
"@type": "Question",
|
||
name: question,
|
||
acceptedAnswer: {
|
||
"@type": "Answer",
|
||
text: list ? `${answer} ${list.join("; ")}.` : answer,
|
||
},
|
||
})),
|
||
};
|
||
}
|