diff --git a/app/about/page.tsx b/app/about/page.tsx index 3fbd1a5..62f53f0 100644 --- a/app/about/page.tsx +++ b/app/about/page.tsx @@ -2,6 +2,15 @@ import React from 'react'; import Link from 'next/link'; import { Eye, Mail, Users, Heart, ExternalLink } from 'lucide-react'; +import type { Metadata } from 'next'; + +export const metadata: Metadata = { + title: 'About CCFW', + description: 'Learn about Cape Coral Friends of Wildlife and our mission to protect Florida wildlife.', +}; + + + export default function AboutPage() { return (
diff --git a/app/donate/page.tsx b/app/donate/page.tsx index 033b92b..14c7742 100644 --- a/app/donate/page.tsx +++ b/app/donate/page.tsx @@ -3,6 +3,15 @@ import { Heart, Shield, Camera, TreePine } from 'lucide-react'; import { api, Campaign } from '@/lib/api'; import DonationCard from '../components/DonationCard'; +import type { Metadata } from 'next'; + +export const metadata: Metadata = { + title: 'Donate', + description: 'Support burrowing owl conservation with a donation to CCFW.', +}; + + + const FALLBACK_CAMPAIGNS: Campaign[] = [ { id: '1', title: 'Land Preservation Fund', diff --git a/app/events/page.tsx b/app/events/page.tsx index 96f32c1..6d5581a 100644 --- a/app/events/page.tsx +++ b/app/events/page.tsx @@ -3,6 +3,15 @@ import { Calendar } from 'lucide-react'; import { api, Event } from '@/lib/api'; import EventCard from '../components/EventCard'; +import type { Metadata } from 'next'; + +export const metadata: Metadata = { + title: 'Events', + description: 'Join CCFW conservation events, bird walks, and community programs.', +}; + + + const FALLBACK_EVENTS: Event[] = [ { id: '1', diff --git a/app/layout.tsx b/app/layout.tsx index 68794ea..5c91882 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,11 +1,44 @@ -import type { Metadata } from 'next'; +import type { Metadata, Viewport } from 'next'; import './globals.css'; import Navbar from './components/Navbar'; import Footer from './components/Footer'; +export const viewport: Viewport = { + width: 'device-width', + initialScale: 1, + themeColor: '#0a1a15', +}; + export const metadata: Metadata = { - title: 'Owl Stream | Cape Coral Friends of Wildlife', - description: 'Live burrowing owl cams, wildlife conservation, and nature in Cape Coral, Florida.', + title: { + default: 'Owl Stream | Cape Coral Friends of Wildlife', + template: '%s | Owl Stream', + }, + description: 'Live burrowing owl cams, wildlife conservation, and nature in Cape Coral, Florida. Watch 24/7 streams, donate, and volunteer with CCFW.', + keywords: ['burrowing owl', 'cape coral', 'wildlife camera', 'live stream', 'conservation', 'Florida wildlife', 'CCFW'], + authors: [{ name: 'Cape Coral Friends of Wildlife' }], + openGraph: { + type: 'website', + locale: 'en_US', + siteName: 'Owl Stream', + title: 'Owl Stream — Live Burrowing Owl Cams', + description: 'Watch Cape Coral\'s burrowing owls live, 24/7. Free wildlife cameras by CCFW.', + images: [{ url: '/og-image.png', width: 1200, height: 630, alt: 'Owl Stream - Live Wildlife Cameras' }], + }, + twitter: { + card: 'summary_large_image', + title: 'Owl Stream — Live Burrowing Owl Cams', + description: 'Watch Cape Coral\'s burrowing owls live, 24/7.', + images: ['/og-image.png'], + }, + robots: { + index: true, + follow: true, + }, + icons: { + icon: '/favicon.svg', + apple: '/apple-touch-icon.png', + }, }; export default function RootLayout({ children }: { children: React.ReactNode }) { diff --git a/app/map/page.tsx b/app/map/page.tsx index b4015d0..9a2bafe 100644 --- a/app/map/page.tsx +++ b/app/map/page.tsx @@ -1,6 +1,15 @@ import React from 'react'; import { Map } from 'lucide-react'; +import type { Metadata } from 'next'; + +export const metadata: Metadata = { + title: 'Burrow Map', + description: 'Interactive map of burrowing owl burrows in Cape Coral, Florida.', +}; + + + export default function MapPage() { return (
diff --git a/app/robots.ts b/app/robots.ts new file mode 100644 index 0000000..c4c07f6 --- /dev/null +++ b/app/robots.ts @@ -0,0 +1,11 @@ +import { MetadataRoute } from 'next'; + +export default function robots(): MetadataRoute.Robots { + return { + rules: { + userAgent: '*', + allow: '/', + }, + sitemap: 'https://owlstream.bizzle.cloud/sitemap.xml', + }; +} diff --git a/app/sitemap.ts b/app/sitemap.ts new file mode 100644 index 0000000..8ec98f9 --- /dev/null +++ b/app/sitemap.ts @@ -0,0 +1,17 @@ +import { MetadataRoute } from 'next'; + +export default function sitemap(): MetadataRoute.Sitemap { + const base = 'https://owlstream.bizzle.cloud'; + const now = new Date(); + + return [ + { url: base, lastModified: now, changeFrequency: 'daily', priority: 1 }, + { url: `${base}/streams`, lastModified: now, changeFrequency: 'hourly', priority: 0.9 }, + { url: `${base}/wildlife`, lastModified: now, changeFrequency: 'monthly', priority: 0.8 }, + { url: `${base}/donate`, lastModified: now, changeFrequency: 'monthly', priority: 0.8 }, + { url: `${base}/volunteer`, lastModified: now, changeFrequency: 'monthly', priority: 0.7 }, + { url: `${base}/events`, lastModified: now, changeFrequency: 'weekly', priority: 0.7 }, + { url: `${base}/map`, lastModified: now, changeFrequency: 'weekly', priority: 0.7 }, + { url: `${base}/about`, lastModified: now, changeFrequency: 'monthly', priority: 0.5 }, + ]; +} diff --git a/app/streams/page.tsx b/app/streams/page.tsx index 7172881..bcf0066 100644 --- a/app/streams/page.tsx +++ b/app/streams/page.tsx @@ -3,6 +3,15 @@ import { Radio } from 'lucide-react'; import { api, Stream } from '@/lib/api'; import StreamCard from '../components/StreamCard'; +import type { Metadata } from 'next'; + +export const metadata: Metadata = { + title: 'Live Cams', + description: 'Watch live wildlife cameras streaming 24/7 from Cape Coral.', +}; + + + async function getStreams(): Promise { try { return await api.getStreams(); } catch { return []; } diff --git a/app/volunteer/page.tsx b/app/volunteer/page.tsx index abd5325..e405dc3 100644 --- a/app/volunteer/page.tsx +++ b/app/volunteer/page.tsx @@ -2,6 +2,15 @@ import React from 'react'; import { Lock, Users, ClipboardList } from 'lucide-react'; import Link from 'next/link'; +import type { Metadata } from 'next'; + +export const metadata: Metadata = { + title: 'Volunteer', + description: 'Join the CCFW volunteer team for owl surveys and habitat restoration.', +}; + + + export default function VolunteerPage() { return (
diff --git a/app/wildlife/page.tsx b/app/wildlife/page.tsx index 91f15e5..076dd14 100644 --- a/app/wildlife/page.tsx +++ b/app/wildlife/page.tsx @@ -3,6 +3,15 @@ import { TreePine } from 'lucide-react'; import { api, Wildlife } from '@/lib/api'; import WildlifeCard from '../components/WildlifeCard'; +import type { Metadata } from 'next'; + +export const metadata: Metadata = { + title: 'Wildlife Guide', + description: 'Discover Cape Coral wildlife including burrowing owls and gopher tortoises.', +}; + + + // Fallback data when API unavailable const FALLBACK: Wildlife[] = [ {