Phase 1: technical SEO foundations

- 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]>
This commit is contained in:
asownerytandClaude Opus 5.5 committed 2026-09-30 20:24:29 +13:00
1 parent 0478ab65e5
commit c085e2b031
23 files changed
+375 -386

No files matched your search

+154
View File
@@ -0,0 +1,154 @@
// 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,
},
})),
};
}