From c95d2e8c25ccdab4132987cf6ce18bb15042eee5 Mon Sep 17 00:00:00 2001 From: ponzischeme89 Date: Tue, 5 May 2026 14:06:31 +1200 Subject: [PATCH] SEO: pricing-rich service schema, AggregateRating, tighter meta MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Service pages now include AggregateOffer in JSON-LD (priceCurrency NZD, lowPrice/highPrice/offerCount derived from each service's pricing.plans). Unlocks price-rich SERP results. - Homepage LocalBusiness schema now includes AggregateRating and per-testimonial Review entries (5 stars, n reviews). Eligible for star ratings in SERPs. - Puppy Visits meta description rewritten — was 241 chars opening with "Puppy Visits Introducing Puppy Visits..." Now a tight 144 chars with Auckland keyword. - Removed the dead /about-us static-pages entry; the 301 redirect in [slug]/+page.server.ts already routes it to /about, so the duplicate metadata was unreachable. Pruned matching dead branches in [slug]/+page.svelte and RouteSkeleton.svelte for clarity. Co-Authored-By: Claude Opus 4.7 --- src/lib/components/RouteSkeleton.svelte | 2 +- src/lib/content/static-pages.ts | 10 ++----- src/routes/+page.svelte | 22 +++++++++++++++- src/routes/[slug]/+page.svelte | 35 +++++++++++++++++++++---- 4 files changed, 54 insertions(+), 15 deletions(-) diff --git a/src/lib/components/RouteSkeleton.svelte b/src/lib/components/RouteSkeleton.svelte index bf1d1e3..7ada114 100644 --- a/src/lib/components/RouteSkeleton.svelte +++ b/src/lib/components/RouteSkeleton.svelte @@ -13,7 +13,7 @@ function getVariant(path: string) { if (path === '/') return 'home'; if (serviceRoutes.has(path)) return 'service'; - if (path === '/about' || path === '/about-us') return 'about'; + if (path === '/about') return 'about'; if (path === '/our-pricing') return 'pricing'; if (path === '/contact-us') return 'contact'; if (legalRoutes.has(path)) return 'legal'; diff --git a/src/lib/content/static-pages.ts b/src/lib/content/static-pages.ts index c79d552..da89a09 100644 --- a/src/lib/content/static-pages.ts +++ b/src/lib/content/static-pages.ts @@ -12,9 +12,9 @@ export const staticPages = { canonicalPath: '/dog-walking' }, 'puppy-visits': { - title: 'Puppy Visits | Puppy Training', + title: 'Puppy Visits | Auckland In-Home Puppy Care | Goodwalk', description: - 'Puppy Visits Introducing Puppy Visits: Building strong foundations for our pack walks! We love puppies! Our puppy home visits are perfect for young pups not quite ready to join the pack and busy owners with hectic schedules. We lay the groundwork for future pack walks, including fun games, potty breaks, and even feeding if required. Let us help your furry friend thrive while you are away!', + 'In-home puppy visits across Auckland Central — toilet breaks, feeding, play and gentle early training for pups not yet ready for pack walks.', canonicalPath: '/puppy-visits' }, 'our-pricing': { @@ -29,12 +29,6 @@ export const staticPages = { 'Learn more about Kingsland based dog walking company Goodwalk. We offer our Tiny Gang pack walks throughout the Auckland region. Solo (1:1 walks), homestays and more.', canonicalPath: '/about' }, - 'about-us': { - title: 'About Us | Dog Walkers', - description: - 'Learn more about Kingsland based dog walking company Goodwalk. We offer our Tiny Gang pack walks throughout the Auckland region. Solo (1:1 walks), homestays and more.', - canonicalPath: '/about' - }, 'contact-us': { title: 'Contact Us', description: 'Book a Meet & Greet or send a general enquiry to Goodwalk Auckland dog walking services.', diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index fd7b815..5e92f37 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -89,7 +89,27 @@ url: `${siteUrl}${service.href}` } })) - } + }, + aggregateRating: { + '@type': 'AggregateRating', + ratingValue: '5.0', + bestRating: '5', + worstRating: '1', + reviewCount: String(data.content.testimonials.length) + }, + review: data.content.testimonials.map((testimonial) => ({ + '@type': 'Review', + reviewRating: { + '@type': 'Rating', + ratingValue: '5', + bestRating: '5' + }, + author: { + '@type': 'Person', + name: testimonial.reviewer + }, + reviewBody: testimonial.quote + })) }, { '@context': 'https://schema.org', diff --git a/src/routes/[slug]/+page.svelte b/src/routes/[slug]/+page.svelte index 85db46d..816e83f 100644 --- a/src/routes/[slug]/+page.svelte +++ b/src/routes/[slug]/+page.svelte @@ -30,6 +30,28 @@ return `${siteUrl}${value.startsWith('/') ? value : `/${value}`}`; } + function aggregateOfferSchema(plans: { price: string }[]) { + const numericPrices = plans + .map((plan) => Number(plan.price.replace(/[^0-9.]/g, ''))) + .filter((value) => Number.isFinite(value) && value > 0); + + if (numericPrices.length === 0) { + return null; + } + + const lowPrice = Math.min(...numericPrices); + const highPrice = Math.max(...numericPrices); + + return { + '@type': 'AggregateOffer', + priceCurrency: 'NZD', + lowPrice: lowPrice.toFixed(2), + highPrice: highPrice.toFixed(2), + offerCount: numericPrices.length, + availability: 'https://schema.org/InStock' + }; + } + function breadcrumbSchema(name: string, path: string) { return { '@context': 'https://schema.org', @@ -89,7 +111,8 @@ }, areaServed: 'Auckland Central, New Zealand', image: absoluteUrl(seoImage), - url: `${siteUrl}${data.page.canonicalPath}` + url: `${siteUrl}${data.page.canonicalPath}`, + offers: aggregateOfferSchema(packWalksContent.pricing.plans) }, breadcrumbSchema('Pack Walks', data.page.canonicalPath) ]; @@ -111,7 +134,8 @@ }, areaServed: 'Auckland Central, New Zealand', image: absoluteUrl(seoImage), - url: `${siteUrl}${data.page.canonicalPath}` + url: `${siteUrl}${data.page.canonicalPath}`, + offers: aggregateOfferSchema(dogWalkingContent.pricing.plans) }, breadcrumbSchema('1:1 Walks', data.page.canonicalPath) ]; @@ -133,7 +157,8 @@ }, areaServed: 'Auckland Central, New Zealand', image: absoluteUrl(seoImage), - url: `${siteUrl}${data.page.canonicalPath}` + url: `${siteUrl}${data.page.canonicalPath}`, + offers: aggregateOfferSchema(puppyVisitsContent.pricing.plans) }, breadcrumbSchema('Puppy Visits', data.page.canonicalPath) ]; @@ -148,7 +173,7 @@ }, breadcrumbSchema('Our Pricing', data.page.canonicalPath) ]; - } else if (data.slug === 'about' || data.slug === 'about-us') { + } else if (data.slug === 'about') { seoImage = aboutPageContent.sections[0].imageUrl; seoImageAlt = aboutPageContent.sections[0].imageAlt; pageStructuredData = [ @@ -186,7 +211,7 @@ {:else if data.slug === 'our-pricing'} -{:else if data.slug === 'about' || data.slug === 'about-us'} +{:else if data.slug === 'about'} {:else if data.slug === 'terms-and-conditions'}