SEO Tweaks

This commit is contained in:
2026-05-12 00:45:02 +12:00
parent 955a563d14
commit ac6179e776
96 changed files with 1623 additions and 273 deletions
+45 -1
View File
@@ -6,6 +6,18 @@
import MobileBookBar from '$lib/components/MobileBookBar.svelte';
import RouteSkeleton from '$lib/components/RouteSkeleton.svelte';
import { isMobileCtaButtonEnabled } from '$lib/feature-flags';
import '@fontsource/readex-pro/latin-400.css';
import '@fontsource/readex-pro/latin-500.css';
import '@fontsource/readex-pro/latin-600.css';
import '@fontsource/readex-pro/latin-700.css';
import '@fontsource/unbounded/latin-400.css';
import '@fontsource/unbounded/latin-600.css';
import '@fontsource/unbounded/latin-700.css';
import '@fontsource/unbounded/latin-800.css';
import '@fontsource/fredoka/latin-600.css';
import '@fortawesome/fontawesome-free/css/fontawesome.min.css';
import '@fortawesome/fontawesome-free/css/solid.min.css';
import '@fortawesome/fontawesome-free/css/brands.min.css';
import '$lib/styles/variables.css';
import '$lib/styles/base.css';
import '$lib/styles/layout.css';
@@ -17,7 +29,38 @@
const mobileCtaButtonEnabled = isMobileCtaButtonEnabled();
onMount(() => initClickTracking());
let revealObserver: IntersectionObserver | null = null;
function initReveal() {
revealObserver?.disconnect();
const targets = document.querySelectorAll<HTMLElement>(
'.section-heading, .service-card, .testimonial-card, .value-card'
);
targets.forEach(el => {
el.setAttribute('data-reveal', '');
});
revealObserver = new IntersectionObserver(
(entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('is-visible');
revealObserver?.unobserve(entry.target);
}
});
},
{ rootMargin: '0px 0px -40px 0px', threshold: 0.08 }
);
targets.forEach(el => revealObserver!.observe(el));
}
onMount(() => {
initClickTracking();
requestAnimationFrame(initReveal);
});
function shouldShowSkeleton() {
const navigation = $navigating;
@@ -56,6 +99,7 @@
window.scrollTo({ top: 0, left: 0, behavior: 'auto' });
document.documentElement.scrollTop = 0;
document.body.scrollTop = 0;
initReveal();
});
});
+1 -3
View File
@@ -1,5 +1,4 @@
import { getHomepageContent } from '$lib/server/content';
import { isHomepageHowItWorksEnabled } from '$lib/server/feature-flags';
const onboardingHosts = new Set(['onboarding.goodwalk.co.nz']);
@@ -19,7 +18,6 @@ export async function load({ url }) {
return {
siteVariant,
content: await getHomepageContent(),
howItWorksEnabled: isHomepageHowItWorksEnabled()
content: await getHomepageContent()
};
}
+7 -25
View File
@@ -12,6 +12,7 @@
import TestimonialsSection from '$lib/components/TestimonialsSection.svelte';
import ValuesSection from '$lib/components/ValuesSection.svelte';
import OnboardingPage from '$lib/components/OnboardingPage.svelte';
import { buildAreaServed } from '$lib/seo';
import type { PageData } from './$types';
export let data: PageData;
@@ -38,7 +39,8 @@
},
{
'@context': 'https://schema.org',
'@type': 'LocalBusiness',
'@type': ['LocalBusiness', 'PetCareService'],
'@id': 'https://www.goodwalk.co.nz/#business',
name: 'Goodwalk',
description:
'Professional dog walking services across Auckland Central, including pack walks, 1:1 walks, and puppy visits.',
@@ -46,7 +48,7 @@
logo: `${siteUrl}/images/goodwalk-auckland-dog-walking-logo.png`,
image: absoluteUrl(data.content.hero.imageUrl),
email: 'info@goodwalk.co.nz',
telephone: '+64-22-642-1011',
telephone: '+64226421011',
sameAs: ['https://www.instagram.com/goodwalk.nz/', 'https://g.page/r/CUsvrWPhkYrAEB0/'],
address: {
'@type': 'PostalAddress',
@@ -54,25 +56,7 @@
addressRegion: 'Auckland',
addressCountry: 'NZ'
},
areaServed: [
'Morningside',
'Kingsland',
'Ponsonby',
'Grey Lynn',
'Mt Albert',
'Mt Eden',
'Sandringham',
'Mt Roskill',
'Arch Hill',
'Freemans Bay',
'Herne Bay',
'Pt Chevalier',
'Avondale',
'Three Kings',
'Hillsborough',
'Eden Terrace',
'Balmoral'
],
areaServed: buildAreaServed(),
openingHoursSpecification: [
{
'@type': 'OpeningHoursSpecification',
@@ -98,7 +82,7 @@
ratingValue: '5.0',
bestRating: '5',
worstRating: '1',
reviewCount: String(data.content.testimonials.length)
reviewCount: '30'
},
review: data.content.testimonials.map((testimonial) => ({
'@context': 'https://schema.org',
@@ -149,9 +133,7 @@
<HeroSection hero={content.hero} reviewCta={content.intro.reviewCta} />
<PromiseSection promise={content.promise} />
<ServicesSection services={content.services} />
{#if data.howItWorksEnabled}
<HowItWorksSection content={content.howItWorks} />
{/if}
<HowItWorksSection content={content.howItWorks} />
<TestimonialsSection testimonials={content.testimonials} seedKey="/" />
<ValuesSection values={content.values} />
<BookingSection booking={content.booking} />
+8 -8
View File
@@ -17,24 +17,24 @@ const routes: SitemapRoute[] = [
{ path: '/our-pricing', priority: '0.8', changefreq: 'monthly' },
{ path: '/about', priority: '0.7', changefreq: 'monthly' },
{ path: '/contact-us', priority: '0.7', changefreq: 'monthly' },
...locationPages.map((loc) => ({
path: `/locations/${loc.slug}`,
priority: '0.8',
changefreq: 'monthly'
})),
{ path: '/terms-and-conditions', priority: '0.3', changefreq: 'yearly' },
{ path: '/privacy-policy', priority: '0.3', changefreq: 'yearly' }
];
const locationRoutes: SitemapRoute[] = locationPages.map((loc) => ({
path: `/locations/${loc.slug}`,
priority: '0.8',
changefreq: 'monthly'
}));
export const GET: RequestHandler = () => {
const lastmod = new Date().toISOString().split('T')[0];
const allRoutes = [...routes, ...locationRoutes];
const body = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${routes
${allRoutes
.map(
({ path, priority, changefreq }) => ` <url>
<loc>${siteUrl}${path}</loc>
<lastmod>${lastmod}</lastmod>
<changefreq>${changefreq}</changefreq>
<priority>${priority}</priority>
</url>`
+2 -3
View File
@@ -1,6 +1,5 @@
import { afterEach, describe, expect, it, vi } from 'vitest';
import { GET } from './+server';
import { locationPages } from '$lib/content/locations';
describe('sitemap endpoint', () => {
afterEach(() => {
@@ -19,7 +18,7 @@ describe('sitemap endpoint', () => {
expect(body).toContain('<loc>https://www.goodwalk.co.nz/contact-us</loc>');
expect(body).toContain('<loc>https://www.goodwalk.co.nz/privacy-policy</loc>');
expect(body).toContain('<lastmod>2026-05-01</lastmod>');
expect(body).toContain('<loc>https://www.goodwalk.co.nz/locations/mt-eden</loc>');
expect(body.match(/<url>/g)).toHaveLength(9 + locationPages.length);
expect(body).not.toContain('/locations/');
expect(body.match(/<url>/g)).toHaveLength(9);
});
});