diff --git a/audits/seo-ai-seo-roadmap.md b/audits/seo-ai-seo-roadmap.md new file mode 100644 index 0000000..df15847 --- /dev/null +++ b/audits/seo-ai-seo-roadmap.md @@ -0,0 +1,555 @@ +# GreenLens SEO + AI-SEO Roadmap + +Stand: 2026-04-10 + +Quelle: +- Keyword-Datensatz: [keyword-research.csv](C:/Users/a931627/Documents/apps/GreenLns/keyword-research.csv) +- Landing Site: [greenlns-landing](C:/Users/a931627/Documents/apps/GreenLns/greenlns-landing) + +## Executive Summary + +GreenLens hat genug Nachfrage im Keyword-Set, um eine kleine, sehr fokussierte SEO-Architektur aufzubauen. Das größte Problem ist nicht fehlendes Suchvolumen, sondern fehlende Seitenabdeckung. Die aktuelle Landing Site deckt im Wesentlichen nur Homepage-, Support- und zwei Vergleichsintentionen ab, obwohl die Keyword-Liste starke Nachfrage in vier Kernbereichen zeigt: + +1. Plant identification +2. Plant health / diagnosis +3. Plant care / reminders +4. German-language app intent + +Zusätzlich gibt es AI-SEO-Potenzial, weil GreenLens bereits mit einem klaren Angle arbeitet: +- plant ER / triage +- next-step diagnosis +- calmer guidance instead of care overload + +Dieser Angle ist für AI-Antworten gut verwertbar, wenn die Inhalte als zitierfähige Antwortblöcke statt als generische Marketing-Flächen gebaut werden. + +## Phase 0: Fixes Before Content Rollout + +Diese Punkte sollten vor dem großen Content-Rollout erledigt werden: + +1. Root-canonical aus dem globalen Layout entfernen und pro Seite selbstreferenzierende Canonicals setzen. +2. Keine `hreflang`-Alternates auf `/` ausgeben, solange keine echten Locale-URLs existieren. +3. Für `/privacy`, `/terms` und `/imprint` eigene `metadata` ergänzen. +4. Platzhalter in den Rechtstexten ersetzen. +5. Encoding-/Mojibake-Probleme in sichtbarem Text bereinigen. +6. `Last updated` und Autoren-/Brand-Signale für neue SEO-Seiten einführen. + +Ohne diese Vorarbeiten besteht das Risiko, dass neue Seiten schlechter indexiert oder im Snippet-Kontext schwächer interpretiert werden. + +## Nachfragebild + +### Brutto aus CSV + +- Rohsumme: ca. `350.220` bis `3.502.200` Suchen / Monat + +### Realistisch dedupliziert + +Nach Clusterung ähnlicher Intentionen und konservativem Überlappungsabschlag: + +- realistisch: ca. `178.052` bis `1.780.520` Suchen / Monat +- Planungs-Midpoint: ca. `979.286` / Monat + +### Interpretation + +- Das ist kein Traffic-Forecast. +- Das ist ein adressierbares Suchinteresse aus der vorhandenen Liste. +- Der größte Hebel liegt klar in `plant identifier app`. +- Der zweitgrößte Hebel liegt in diagnosis/symptom content und German app intent. + +## Priorisierte Seitenarchitektur + +### Wave 1: Highest ROI + +#### 1. `/plant-identifier-app` + +- Primärkeyword: `plant identifier app` +- Unterstützende Keywords: + - `plant identifier` + - `identify plants by photo` + - `identify plant from picture` + - `plant recognition app` + - `plant id app` + - `free plant identifier app` + - `app to identify plants` + - `ai plant identifier` +- Realistisches Seitenpotenzial: `140.842` bis `1.408.420` +- Planungs-Midpoint: `774.631` + +Ziel: +- Haupt-SEO-Landingpage für die Kategorie +- AI-citable Definition und evaluation page + +Title: +- `Plant Identifier App for Fast Diagnosis and Care | GreenLens` + +Meta Description: +- `GreenLens is a plant identifier app that helps you identify plants by photo, diagnose common plant problems, and get the next best care step in one app.` + +H1: +- `Plant Identifier App That Goes Beyond Naming the Plant` + +Core outline: +- What is a plant identifier app? +- How GreenLens identifies plants by photo +- Why plant identification alone is not enough +- GreenLens vs generic plant ID apps +- FAQ + +AI-SEO answer blocks: +- 40-60 word definition block directly under H1 +- short “how it works” numbered list +- table: `GreenLens vs generic plant identifier apps` +- 3-5 symptom-based mini use cases +- FAQ with natural-language questions + +Schema: +- `SoftwareApplication` +- `FAQPage` +- optional `HowTo` + +Internal links: +- link to `/plant-disease-identifier` +- link to `/plant-care-app` +- link to `/vs/inaturalist` +- link to App Store CTA + +Notes: +- This page should be the internal-link hub for the whole organic cluster. + +#### 2. `/plant-disease-identifier` + +- Primärkeyword: `plant disease identifier` +- Unterstützende Keywords: + - `plant health checker` + - `sick plant diagnosis` + - `plant disease app` + - `plant problem diagnosis` + - `plant health app` + - `pest identification` + - `plant diagnosis app` +- Realistisches Seitenpotenzial: `1.900` bis `19.000` +- Planungs-Midpoint: `10.450` + +Ziel: +- Category page for plant diagnosis and symptom-led queries +- Strong AI-overview target because the query is informational and evaluative + +Title: +- `Plant Disease Identifier for Houseplant Problems | GreenLens` + +Meta Description: +- `Use GreenLens as a plant disease identifier to check common plant problems, understand symptoms, and decide on the next safe care step.` + +H1: +- `Plant Disease Identifier for Real-World Plant Problems` + +Core outline: +- What a plant disease identifier can and cannot do +- Common symptoms GreenLens helps interpret +- How to avoid wrong next steps +- When a symptom is likely not a disease +- FAQ + +AI-SEO answer blocks: +- “What is a plant disease identifier?” answer block +- symptom matrix: + - yellow leaves + - brown leaves + - soft stems + - pest signs +- “most likely cause vs safest next step” table +- FAQ framed around beginner decisions + +Schema: +- `FAQPage` +- `HowTo` for diagnosis workflow + +Internal links: +- `/plant-identifier-app` +- future `/plant-leaves-turning-yellow` +- future `/brown-leaves-on-houseplants` + +#### 3. `/plant-care-app` + +- Primärkeyword: `plant care app` +- Unterstützende Keywords: + - `plant care` + - `plant watering reminder` + - `plant watering app` + - `plant care reminder app` + - `houseplant care app` + - `indoor plant care app` +- Realistisches Seitenpotenzial: `1.254` bis `12.540` +- Planungs-Midpoint: `6.897` + +Ziel: +- Category page for ongoing care and reminder intent +- Commercial-intent support page that complements diagnosis pages + +Title: +- `Plant Care App for Reminders, Routines, and Recovery | GreenLens` + +Meta Description: +- `GreenLens is a plant care app for reminders, care routines, plant tracking, and symptom-based next steps when your plant starts to struggle.` + +H1: +- `Plant Care App for Better Routines and Better Decisions` + +Core outline: +- Why most care apps stop at reminders +- What GreenLens tracks +- Reminder logic vs real plant context +- Care routines for indoor plant owners +- FAQ + +AI-SEO answer blocks: +- direct answer: what a plant care app helps with +- feature table: reminders, collection, scan, diagnosis, care notes +- short “when reminders help vs when they hurt” section + +Schema: +- `SoftwareApplication` +- `FAQPage` + +Internal links: +- `/plant-identifier-app` +- `/plant-disease-identifier` +- future `/plant-tracker-app` + +#### 4. `/pflanzen-erkennen-app` + +- Primärkeyword: `pflanzen erkennen app` +- Unterstützende Keywords: + - `pflanzenerkennung app` + - `pflanzen bestimmen app` + - `pflanzen app` + - `pflanzen scanner app` + - `pflanzen identifizieren app` +- Realistisches Seitenpotenzial: `1.640` bis `16.400` +- Planungs-Midpoint: `9.020` + +Ziel: +- Separate German landing page for German app-intent queries +- Also strong AI-citation candidate for German-language questions + +Title: +- `Pflanzen Erkennen App mit Diagnose und Pflegehilfe | GreenLens` + +Meta Description: +- `GreenLens ist eine Pflanzen-Erkennen-App, mit der du Pflanzen per Foto bestimmen, Probleme einordnen und die nächsten Pflegeschritte klarer ableiten kannst.` + +H1: +- `Pflanzen Erkennen App fuer Fotoerkennung und Pflanzenhilfe` + +Core outline: +- Was ist eine Pflanzen-Erkennen-App? +- Pflanzen per Foto bestimmen +- Warum Bestimmung allein nicht reicht +- GreenLens fuer Diagnose und naechste Schritte +- FAQ + +AI-SEO answer blocks: +- direkte Antwort auf Deutsch unter dem H1 +- “So funktioniert es” als nummerierte Liste +- Vergleichstabelle: `GreenLens vs klassische Pflanzen-Apps` +- FAQ in natuerlicher deutscher Fragesprache + +Schema: +- `SoftwareApplication` +- `FAQPage` + +Internal links: +- `/plant-identifier-app` +- optional future `/zimmerpflanzen` +- support/legal pages + +Notes: +- Diese Seite sollte nicht nur die Homepage uebersetzen, sondern German intent wirklich bedienen. + +#### 5. `/vs/inaturalist` + +- Primärkeyword: `inaturalist` +- Unterstützende Keywords: + - category fit: alternative / evaluation intent +- Realistisches Seitenpotenzial: `10.000` bis `100.000` +- Planungs-Midpoint: `55.000` + +Ziel: +- Comparison page with high citation likelihood in AI answers +- Complements existing `/vs/picturethis` and `/vs/plantum` + +Title: +- `GreenLens vs iNaturalist for Plant Identification and Diagnosis` + +Meta Description: +- `Compare GreenLens vs iNaturalist for plant identification, plant diagnosis, next-step care guidance, and beginner-friendly decision support.` + +H1: +- `GreenLens vs iNaturalist` + +Core outline: +- who each product is for +- biodiversity/community app vs plant triage workflow +- identification depth vs next-step diagnosis +- beginner clarity vs expert observation workflow +- FAQ + +AI-SEO answer blocks: +- fair comparison summary in first 60 words +- structured comparison table +- “choose GreenLens if / choose iNaturalist if” bullets +- explicit caveat on where iNaturalist is stronger + +Schema: +- `FAQPage` +- optional `ItemList`-style structured comparison + +Internal links: +- `/plant-identifier-app` +- `/plant-disease-identifier` +- existing comparison pages + +### Wave 2: Strong Follow-Up Pages + +Diese Seiten haben gute Ergänzungsfunktion oder Long-Tail-/AI-SEO-Wert: + +1. `/best-plant-identification-app` +2. `/plant-leaves-turning-yellow` +3. `/brown-leaves-on-houseplants` +4. `/zimmerpflanzen` +5. `/identificador-de-plantas` +6. `/plant-tracker-app` + +## Cannibalization Rules + +Damit die Seiten sich nicht gegenseitig schwächen: + +- `/plant-identifier-app` + - category page + - broad commercial + informational intent +- `/plant-disease-identifier` + - diagnosis-specific category page +- `/plant-care-app` + - routine/reminder/tracking intent +- `/pflanzen-erkennen-app` + - German-language category page +- `/vs/*` + - comparison intent only +- symptom pages + - narrow problem-specific intent only + +Regel: +- Jede Seite braucht ein klar eigenes Primärkeyword. +- Das Primärkeyword muss in `title`, `H1`, intro copy, slug und interner Verlinkung konsistent sein. +- Keine zweite Seite sollte dasselbe Keyword-Set als Primärziel bekommen. + +## AI-SEO Content Pattern + +Alle neuen Pages sollten dieselbe Grundstruktur für AI-Citation verwenden. + +### Required above-the-fold structure + +1. Direct answer paragraph +2. Clear H1 matching the query +3. 3-bullet summary of when GreenLens is useful +4. Primary CTA + +### Required extractable blocks + +1. Definition block + - 40-60 words + - answers the primary query directly + +2. Comparison block + - table or side-by-side bullets + - especially important for category and alternative pages + +3. Decision block + - “Choose GreenLens if...” + - “Not the best fit if...” + +4. FAQ block + - 4-6 natural-language questions + - answers should stand alone without surrounding context + +5. Freshness block + - visible “Last updated” + - visible review/update cadence + +### Recommended AI-citation signals + +- specific numbers where they are true and defensible +- product facts in plain language +- one-sentence summary paragraphs +- balanced tone on comparison pages +- author/reviewer attribution +- sources for third-party claims + +## Metadata Rules + +For all new pages: + +- title length target: `50-60` chars where possible +- description target: `140-160` chars +- self-referencing canonical +- Open Graph aligned to title and description +- one H1 only + +Template: + +```txt +Title: [Primary Keyword] + [specific benefit] | GreenLens +Meta: Clear value proposition with keyword, no fluff, no repetition +H1: Match query closely, but read naturally +``` + +## Schema Plan + +Minimum schema for rollout: + +1. Global: + - `Organization` + - `SoftwareApplication` + +2. Per page: + - category pages: `FAQPage` + - workflow pages: `HowTo` + - comparison pages: `FAQPage` + +Optional later: + +- `Review` +- `AggregateRating` +- `BreadcrumbList` + +## Internal Linking Plan + +### Homepage + +Homepage should link prominently to: + +- `/plant-identifier-app` +- `/plant-disease-identifier` +- `/plant-care-app` +- `/pflanzen-erkennen-app` +- `/vs/inaturalist` + +### Category hub logic + +- `/plant-identifier-app` links to all other money pages +- `/plant-disease-identifier` links to symptom pages +- `/plant-care-app` links to tracker/reminder pages +- `/pflanzen-erkennen-app` links to German support cluster +- `/vs/*` links back into category pages + +### Anchor text examples + +Use varied, natural anchors: + +- `plant identifier app` +- `plant disease identifier` +- `plant care app` +- `Pflanzen erkennen App` +- `compare GreenLens and iNaturalist` + +Do not overuse exact-match anchors sitewide. + +## AI Visibility Monitoring Plan + +Test these queries monthly in: + +- Google AI Overviews +- ChatGPT search +- Perplexity + +### Priority queries + +1. `plant identifier app` +2. `identify plants by photo` +3. `plant disease identifier` +4. `plant care app` +5. `best plant identification app` +6. `GreenLens vs PictureThis` +7. `GreenLens vs Plantum` +8. `GreenLens vs iNaturalist` +9. `pflanzen erkennen app` +10. `plant leaves turning yellow` + +### Tracking sheet fields + +- query +- platform +- AI answer present +- GreenLens cited +- competitor cited +- source page cited +- sentiment / framing + +## Off-Site AI-SEO Presence + +AI visibility will not come only from GreenLens pages. Parallel actions: + +1. Expand comparison page set for major apps in the category. +2. Build review-site presence where relevant. +3. Seek mentions in plant-care roundups and app lists. +4. Create at least one referenceable “best app” style page with a balanced tone. +5. Consider one explainer asset on YouTube for plant diagnosis workflows. + +## 30/60/90 Rollout + +### First 30 days + +1. Fix canonicals, metadata inheritance, legal placeholders, encoding issues. +2. Build: + - `/plant-identifier-app` + - `/plant-disease-identifier` + - `/plant-care-app` +3. Add homepage internal links to these pages. + +### Days 31-60 + +1. Build `/pflanzen-erkennen-app` +2. Build `/vs/inaturalist` +3. Add page-specific schema and update sitemap +4. Start AI visibility checks on top 10 queries + +### Days 61-90 + +1. Build symptom pages: + - `/plant-leaves-turning-yellow` + - `/brown-leaves-on-houseplants` +2. Build `/best-plant-identification-app` +3. Build `/zimmerpflanzen` +4. Review internal links and refresh snippets based on early ranking/citation behavior + +## Implementation Notes for This Repo + +Recommended file pattern in `greenlns-landing/app`: + +- `app/plant-identifier-app/page.tsx` +- `app/plant-disease-identifier/page.tsx` +- `app/plant-care-app/page.tsx` +- `app/pflanzen-erkennen-app/page.tsx` +- `app/vs/inaturalist/page.tsx` + +Recommended shared components: + +- reusable FAQ component +- reusable comparison table component +- reusable page hero component for category pages +- shared page-level metadata helper + +## Recommended First Build Order + +If only one wave is built now: + +1. `/plant-identifier-app` +2. `/plant-disease-identifier` +3. `/plant-care-app` +4. `/pflanzen-erkennen-app` +5. `/vs/inaturalist` + +Reason: +- highest combined SEO + AI-SEO leverage +- strongest match to existing product positioning +- cleanest internal-link structure +- fastest path to broad category coverage diff --git a/greenlns-landing/app/layout.tsx b/greenlns-landing/app/layout.tsx index a01ffb2..0069f79 100644 --- a/greenlns-landing/app/layout.tsx +++ b/greenlns-landing/app/layout.tsx @@ -34,15 +34,6 @@ export const metadata: Metadata = { title: 'GreenLens - Plant Identifier and Care Planner', description: 'Identify plants, get care guidance, and manage your collection with GreenLens.', }, - alternates: { - canonical: '/', - languages: { - de: '/', - en: '/', - es: '/', - 'x-default': '/', - }, - }, } export default async function RootLayout({ children }: { children: React.ReactNode }) { diff --git a/greenlns-landing/app/pflanzen-erkennen-app/page.tsx b/greenlns-landing/app/pflanzen-erkennen-app/page.tsx new file mode 100644 index 0000000..d2f8e4c --- /dev/null +++ b/greenlns-landing/app/pflanzen-erkennen-app/page.tsx @@ -0,0 +1,33 @@ +import type { Metadata } from 'next' +import { notFound } from 'next/navigation' +import SeoCategoryPage from '@/components/SeoCategoryPage' +import { getSeoPageBySlug } from '@/lib/seoPages' +import { siteConfig } from '@/lib/site' + +const profile = getSeoPageBySlug('pflanzen-erkennen-app') + +export const metadata: Metadata = !profile + ? {} + : { + title: profile.metaTitle, + description: profile.metaDescription, + alternates: { canonical: profile.canonical }, + openGraph: { + title: profile.metaTitle, + description: profile.metaDescription, + url: `${siteConfig.domain}${profile.canonical}`, + type: 'website', + images: [{ url: '/og-image.png', width: 1200, height: 630, alt: profile.metaTitle }], + }, + twitter: { + card: 'summary_large_image', + title: profile.metaTitle, + description: profile.metaDescription, + images: ['/og-image.png'], + }, + } + +export default function Page() { + if (!profile) notFound() + return +} diff --git a/greenlns-landing/app/plant-care-app/page.tsx b/greenlns-landing/app/plant-care-app/page.tsx new file mode 100644 index 0000000..ef62562 --- /dev/null +++ b/greenlns-landing/app/plant-care-app/page.tsx @@ -0,0 +1,33 @@ +import type { Metadata } from 'next' +import { notFound } from 'next/navigation' +import SeoCategoryPage from '@/components/SeoCategoryPage' +import { getSeoPageBySlug } from '@/lib/seoPages' +import { siteConfig } from '@/lib/site' + +const profile = getSeoPageBySlug('plant-care-app') + +export const metadata: Metadata = !profile + ? {} + : { + title: profile.metaTitle, + description: profile.metaDescription, + alternates: { canonical: profile.canonical }, + openGraph: { + title: profile.metaTitle, + description: profile.metaDescription, + url: `${siteConfig.domain}${profile.canonical}`, + type: 'website', + images: [{ url: '/og-image.png', width: 1200, height: 630, alt: profile.metaTitle }], + }, + twitter: { + card: 'summary_large_image', + title: profile.metaTitle, + description: profile.metaDescription, + images: ['/og-image.png'], + }, + } + +export default function Page() { + if (!profile) notFound() + return +} diff --git a/greenlns-landing/app/plant-disease-identifier/page.tsx b/greenlns-landing/app/plant-disease-identifier/page.tsx new file mode 100644 index 0000000..591437d --- /dev/null +++ b/greenlns-landing/app/plant-disease-identifier/page.tsx @@ -0,0 +1,33 @@ +import type { Metadata } from 'next' +import { notFound } from 'next/navigation' +import SeoCategoryPage from '@/components/SeoCategoryPage' +import { getSeoPageBySlug } from '@/lib/seoPages' +import { siteConfig } from '@/lib/site' + +const profile = getSeoPageBySlug('plant-disease-identifier') + +export const metadata: Metadata = !profile + ? {} + : { + title: profile.metaTitle, + description: profile.metaDescription, + alternates: { canonical: profile.canonical }, + openGraph: { + title: profile.metaTitle, + description: profile.metaDescription, + url: `${siteConfig.domain}${profile.canonical}`, + type: 'website', + images: [{ url: '/og-image.png', width: 1200, height: 630, alt: profile.metaTitle }], + }, + twitter: { + card: 'summary_large_image', + title: profile.metaTitle, + description: profile.metaDescription, + images: ['/og-image.png'], + }, + } + +export default function Page() { + if (!profile) notFound() + return +} diff --git a/greenlns-landing/app/plant-identifier-app/page.tsx b/greenlns-landing/app/plant-identifier-app/page.tsx new file mode 100644 index 0000000..b3a1d96 --- /dev/null +++ b/greenlns-landing/app/plant-identifier-app/page.tsx @@ -0,0 +1,33 @@ +import type { Metadata } from 'next' +import { notFound } from 'next/navigation' +import SeoCategoryPage from '@/components/SeoCategoryPage' +import { getSeoPageBySlug } from '@/lib/seoPages' +import { siteConfig } from '@/lib/site' + +const profile = getSeoPageBySlug('plant-identifier-app') + +export const metadata: Metadata = !profile + ? {} + : { + title: profile.metaTitle, + description: profile.metaDescription, + alternates: { canonical: profile.canonical }, + openGraph: { + title: profile.metaTitle, + description: profile.metaDescription, + url: `${siteConfig.domain}${profile.canonical}`, + type: 'website', + images: [{ url: '/og-image.png', width: 1200, height: 630, alt: profile.metaTitle }], + }, + twitter: { + card: 'summary_large_image', + title: profile.metaTitle, + description: profile.metaDescription, + images: ['/og-image.png'], + }, + } + +export default function Page() { + if (!profile) notFound() + return +} diff --git a/greenlns-landing/app/sitemap.ts b/greenlns-landing/app/sitemap.ts index 58633c0..18d663f 100644 --- a/greenlns-landing/app/sitemap.ts +++ b/greenlns-landing/app/sitemap.ts @@ -16,6 +16,30 @@ export default function sitemap(): MetadataRoute.Sitemap { changeFrequency: 'monthly', priority: 0.5, }, + { + url: `${baseUrl}/plant-identifier-app`, + lastModified: new Date('2026-04-12'), + changeFrequency: 'monthly', + priority: 0.8, + }, + { + url: `${baseUrl}/plant-disease-identifier`, + lastModified: new Date('2026-04-12'), + changeFrequency: 'monthly', + priority: 0.75, + }, + { + url: `${baseUrl}/plant-care-app`, + lastModified: new Date('2026-04-12'), + changeFrequency: 'monthly', + priority: 0.75, + }, + { + url: `${baseUrl}/pflanzen-erkennen-app`, + lastModified: new Date('2026-04-12'), + changeFrequency: 'monthly', + priority: 0.75, + }, { url: `${baseUrl}/vs/picturethis`, lastModified: new Date('2026-04-10'), @@ -28,6 +52,12 @@ export default function sitemap(): MetadataRoute.Sitemap { changeFrequency: 'monthly', priority: 0.65, }, + { + url: `${baseUrl}/vs/inaturalist`, + lastModified: new Date('2026-04-12'), + changeFrequency: 'monthly', + priority: 0.65, + }, { url: `${baseUrl}/imprint`, lastModified: new Date('2026-04-08'), diff --git a/greenlns-landing/components/Footer.tsx b/greenlns-landing/components/Footer.tsx index 1347a03..cb1d454 100644 --- a/greenlns-landing/components/Footer.tsx +++ b/greenlns-landing/components/Footer.tsx @@ -27,20 +27,25 @@ export default function Footer() { {t.footer.cols.map((col, ci) => (
{col.title}
- {col.links.map((label, li) => ( - - {label} - - ))} - {ci === 1 && ( - <> - GreenLens vs PictureThis - GreenLens vs Plantum - - )} -
- ))} - + {col.links.map((label, li) => ( + + {label} + + ))} + {ci === 1 && ( + <> + Plant Identifier App + Plant Disease Identifier + Plant Care App + Pflanzen erkennen + GreenLens vs PictureThis + GreenLens vs Plantum + GreenLens vs iNaturalist + + )} + + ))} + diff --git a/greenlns-landing/components/SeoCategoryPage.tsx b/greenlns-landing/components/SeoCategoryPage.tsx new file mode 100644 index 0000000..b6505af --- /dev/null +++ b/greenlns-landing/components/SeoCategoryPage.tsx @@ -0,0 +1,177 @@ +import Link from 'next/link' +import Navbar from '@/components/Navbar' +import CTA from '@/components/CTA' +import Footer from '@/components/Footer' +import type { SeoPageProfile } from '@/lib/seoPages' +import { siteConfig, hasIosStoreUrl } from '@/lib/site' + +interface SeoCategoryPageProps { + profile: SeoPageProfile +} + +export default function SeoCategoryPage({ profile }: SeoCategoryPageProps) { + const faqSchema = { + '@context': 'https://schema.org', + '@type': 'FAQPage', + mainEntity: profile.faqs.map((item) => ({ + '@type': 'Question', + name: item.question, + acceptedAnswer: { + '@type': 'Answer', + text: item.answer, + }, + })), + } + + const appSchema = profile.includeAppSchema + ? { + '@context': 'https://schema.org', + '@type': 'SoftwareApplication', + name: siteConfig.name, + operatingSystem: 'iOS, Android', + applicationCategory: 'LifestyleApplication', + description: profile.directAnswer, + ...(hasIosStoreUrl && { downloadUrl: siteConfig.iosAppStoreUrl }), + offers: { + '@type': 'Offer', + price: '0', + priceCurrency: 'EUR', + }, + } + : null + + return ( + <> +