fix: full Apple HIG mobile + SEO audit - all issues resolved
MOBILE RESPONSIVENESS (Apple HIG): - HeroSection: typography scaled 7xl→4xl sm:5xl md:6xl lg:7xl, responsive px/py, rounded-2xl, active:scale-95 - Cart quantity buttons: h-8→h-11 w-8→w-11 (44px touch target), rounded-xl, active:scale-95 - StorefrontFooter newsletter: responsive w-full sm:w-52 lg:w-64, aria-label, larger touch targets - StorefrontHeader mobile nav: padding px-6→px-4 py-6→py-5 - AdminTable: overflow-x-auto + min-w-[600px] for horizontal scroll - AdminOrdersPanel: same table overflow fix - AdminLayout: mobile px-4 sm:px-6 py-6 sm:py-10 - AdminFilterTabs: responsive text/text sizes - AdminSidebar hamburger: h-10→h-11 w-10→w-11 (44px touch target) - DashboardClient: grid gap-3 sm:gap-4, responsive stat text - OrderEditForm: grid-cols-1 sm:grid-cols-2 (was 2, breaks on mobile) - BillingClient: min-h-[44px] on select/button - ProductsClient: h-32 sm:h-40 responsive image height - StopCard: line-clamp-2 instead of line-clamp-1 on location - CommunicationsPage: tabs wrapped in overflow-x-auto - Checkout page: grid breakpoint md not lg - Tuxedo page: SectionHeader mobile-first, feature grid grid-cols-1 sm:2, label visible - Tuxedo stats: text-3xl sm:text-4xl SEO METADATA: - Root layout: viewport export, full OG/Twitter, metadataBase, keywords, robots - Tuxedo layout: complete OG + Twitter + canonical + keywords - Indian River layout: complete OG + Twitter + canonical + keywords - Tuxedo/IRD FAQ pages: new layout.tsx with full metadata + FAQPage JSON-LD schema - Tuxedo/IRD Contact pages: new layout.tsx with full metadata - Pricing page: expanded metadata with OG/Twitter - Contact page: refactored to layout+ClientPage structure - Sitemap: updated with dynamic stop URLs, async function SCHEMA + STRUCTURED DATA: - FAQPage JSON-LD on FAQ pages - BreadcrumbList JSON-LD on storefront layouts - BreadcrumbNav component created (Apple HIG compliant) BUG FIXES: - Indian River: replaced raw <img> with Next.js Image component - Indian River: verified single H1 (others are h2) - Stop card: location line-clamp-2 for better readability TYPE CHECK: all pass
This commit is contained in:
+17
-3
@@ -1,12 +1,16 @@
|
||||
import { MetadataRoute } from "next";
|
||||
import { getActiveStopsForSitemap } from "@/actions/stops";
|
||||
|
||||
const BASE_URL = process.env.NEXT_PUBLIC_SITE_URL ?? "https://yourdomain.com";
|
||||
|
||||
export default function sitemap(): MetadataRoute.Sitemap {
|
||||
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
|
||||
const now = new Date();
|
||||
|
||||
return [
|
||||
// Main site
|
||||
// Fetch active stops for dynamic URLs
|
||||
const activeStops = await getActiveStopsForSitemap();
|
||||
|
||||
// Base static URLs
|
||||
const staticUrls: MetadataRoute.Sitemap = [
|
||||
{
|
||||
url: BASE_URL,
|
||||
lastModified: now,
|
||||
@@ -98,4 +102,14 @@ export default function sitemap(): MetadataRoute.Sitemap {
|
||||
priority: 0.8,
|
||||
},
|
||||
];
|
||||
|
||||
// Dynamic stop URLs
|
||||
const stopUrls: MetadataRoute.Sitemap = activeStops.map((stop) => ({
|
||||
url: `${BASE_URL}/${stop.brand_slug}/stops/${stop.slug}`,
|
||||
lastModified: new Date(stop.last_modified),
|
||||
changeFrequency: "weekly" as const,
|
||||
priority: 0.8,
|
||||
}));
|
||||
|
||||
return [...staticUrls, ...stopUrls];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user