Files
route-commerce/src/app/indian-river-direct/layout.tsx
T
Tyler 4ebbc6dacf
Deploy to route.crispygoat.com / deploy (push) Successful in 4m21s
feat: smooth view transitions, no skeleton flash
User pain point: skeleton loading.tsx files made the app feel like
a sequence of page reloads, exposing backend latency. Replaced with
a single 1px shimmer bar + crossfade via React's <ViewTransition>.

Changes:
- Enable experimental.viewTransition in next.config.ts
- Add SmoothViewTransition wrapper (ViewTransition name=page-content)
- Add LoadingFade component: thin animated bar instead of skeleton
- Add RouteAnnouncer for a11y (screen readers + focus reset)
- Add ::view-transition-old/new CSS for the crossfade (220ms, no
  jarring slide, respects prefers-reduced-motion)
- Wrap admin/tuxedo/IRD layout children in SmoothViewTransition
  (sidebar/header/footer stay mounted; only the body fades)
- Replace 19 skeleton loading.tsx files with the fade component

Result: navigation now feels like a single app, not a series of
preload-and-render events. The user never sees a 'skeleton of the
page they're about to load.'
2026-06-16 23:37:00 -06:00

112 lines
4.0 KiB
TypeScript

import type { Metadata, Viewport } from "next";
import { SmoothViewTransition } from "@/components/transitions/SmoothViewTransition";
const BASE_URL = process.env.NEXT_PUBLIC_SITE_URL ?? "https://routecommerce.com";
// Structured data for the Indian River Direct storefront.
// LocalBusiness + BreadcrumbList for the family farm brand.
const indianRiverStructuredData = {
"@context": "https://schema.org",
"@graph": [
{
"@type": "BreadcrumbList",
itemListElement: [
{ "@type": "ListItem", position: 1, name: "Home", item: BASE_URL },
{ "@type": "ListItem", position: 2, name: "Indian River Direct", item: `${BASE_URL}/indian-river-direct` },
],
},
{
"@type": "LocalBusiness",
"@id": `${BASE_URL}/indian-river-direct/#localbusiness`,
name: "Indian River Direct",
description:
"Fresh peaches and citrus from our Florida groves to truckload sales in your neighborhood. Family-owned since 1985.",
url: `${BASE_URL}/indian-river-direct`,
image: `${BASE_URL}/og-default.svg`,
priceRange: "$$",
address: {
"@type": "PostalAddress",
addressRegion: "FL",
addressCountry: "US",
},
foundingDate: "1985",
},
],
};
export const metadata: Metadata = {
title: {
default: "Indian River Direct | Peach & Citrus Truckload",
template: "%s | Indian River Direct",
},
description: "Fresh peaches and citrus from our Florida groves to truckload sales in your neighborhood. Family-owned since 1985. Pre-order now for 2026 season.",
keywords: ["peaches", "citrus", "Florida produce", "truckload sales", "fresh fruit", "Indian River", "wholesale peaches"],
authors: [{ name: "Indian River Direct" }],
creator: "Indian River Direct",
publisher: "Indian River Direct",
openGraph: {
title: "Indian River Direct | Fresh Peaches & Citrus",
description: "Fresh peaches and citrus from our Florida groves to truckload sales in your neighborhood. Family-owned since 1985.",
url: `${BASE_URL}/indian-river-direct`,
siteName: "Indian River Direct",
locale: "en_US",
type: "website",
images: [
{
url: "/og-default.svg",
width: 1200,
height: 630,
alt: "Indian River Direct - Fresh Peaches & Citrus",
},
],
},
twitter: {
card: "summary_large_image",
title: "Indian River Direct | Peach & Citrus Truckload",
description: "Fresh peaches and citrus from our Florida groves. Family-owned since 1985. Pre-order for 2026 season.",
site: "@IndianRiverDirect",
creator: "@IndianRiverDirect",
images: ["/og-default.svg"],
},
alternates: {
canonical: `${BASE_URL}/indian-river-direct`,
},
robots: {
index: true,
follow: true,
googleBot: {
index: true,
follow: true,
},
},
other: {
"application/ld+json": JSON.stringify(indianRiverStructuredData),
},
};
export const viewport: Viewport = {
width: "device-width",
initialScale: 1,
maximumScale: 5,
};
export default function IndianRiverLayout({ children }: { children: React.ReactNode }) {
return (
<div className="min-h-screen relative">
{/* Glass morphism gradient background */}
<div className="fixed inset-0 bg-gradient-to-br from-blue-100/40 via-white/60 to-blue-50/30" />
{/* Decorative glass orbs */}
<div className="fixed inset-0 pointer-events-none overflow-hidden">
<div className="absolute -top-40 -right-40 w-96 h-96 bg-gradient-to-br from-blue-200/30 to-transparent rounded-full blur-3xl" />
<div className="absolute top-1/3 -left-20 w-72 h-72 bg-gradient-to-br from-blue-100/25 to-transparent rounded-full blur-2xl" />
<div className="absolute bottom-0 right-1/4 w-80 h-80 bg-gradient-to-br from-blue-50/40 to-transparent rounded-full blur-3xl" />
</div>
{/* Content wrapper — crossfades on navigation. */}
<div id="page-content" className="relative outline-none">
<SmoothViewTransition>{children}</SmoothViewTransition>
</div>
</div>
);
}