This commit is contained in:
2026-07-10 13:27:29 +02:00
parent 5c48def4e1
commit 53bac4e2b4
35 changed files with 466 additions and 320 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 311 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 KiB

View File

@@ -1,5 +1,6 @@
import type { Metadata } from 'next'
import Home from '../page'
import { siteConfig } from '@/lib/site'
export const metadata: Metadata = {
title: 'GreenLens - Plant Identifier & Care Planner',
@@ -18,11 +19,18 @@ export const metadata: Metadata = {
title: 'GreenLens - Plant Identifier & Care Planner',
description:
'Scan plants by photo, understand what they need, and keep care, reminders, and your collection in one app.',
url: `${siteConfig.domain}/en`,
type: 'website',
locale: 'en_US',
},
twitter: {
card: 'summary_large_image',
title: 'GreenLens - Plant Identifier & Care Planner',
description:
'Scan plants by photo, understand what they need, and keep care, reminders, and your collection in one app.',
},
}
export default function EnglishHomePage() {
return <Home />
return <Home locale="en" />
}

View File

@@ -23,8 +23,14 @@ export const metadata: Metadata = {
type: 'website',
locale: 'es_ES',
},
twitter: {
card: 'summary_large_image',
title: 'GreenLens - Identificar y cuidar plantas',
description:
'Identifica plantas por foto, organiza cuidados, recibe recordatorios y diagnostica síntomas comunes con GreenLens.',
},
}
export default function SpanishHomePage() {
return <Home />
return <Home locale="es" />
}

View File

@@ -3,7 +3,7 @@ import { cookies } from 'next/headers'
import { headers } from 'next/headers'
import './globals.css'
import { LangProvider } from '@/context/LangContext'
import { siteConfig, hasIosStoreUrl } from '@/lib/site'
import { siteConfig, hasIosStoreUrl, hasAndroidStoreUrl } from '@/lib/site'
export const metadata: Metadata = {
metadataBase: new URL(siteConfig.domain),
@@ -54,6 +54,20 @@ export default async function RootLayout({ children }: { children: React.ReactNo
const lang = (routeLang ?? cookieStore.get('lang')?.value ?? 'de') as 'de' | 'en' | 'es'
const validLangs = ['de', 'en', 'es']
const htmlLang = validLangs.includes(lang) ? lang : 'de'
const schemaDescription = {
de: 'Pflanzen per Foto einordnen, Pflegepläne nutzen und sichtbare Pflanzenprobleme prüfen.',
en: 'Assess plants from photos, use care plans, and review visible plant problems.',
es: 'Evalúa plantas con fotos, utiliza planes de cuidado y revisa problemas visibles.',
}[htmlLang]
const organizationDescription = {
de: 'GreenLens ist eine App zur Pflanzenerkennung und Pflegeplanung.',
en: 'GreenLens is an app for plant identification and care planning.',
es: 'GreenLens es una app para identificar plantas y planificar sus cuidados.',
}[htmlLang]
const operatingSystems = [
hasIosStoreUrl ? 'iOS' : null,
hasAndroidStoreUrl ? 'Android' : null,
].filter((value): value is string => Boolean(value))
return (
<html lang={htmlLang}>
@@ -76,11 +90,10 @@ export default async function RootLayout({ children }: { children: React.ReactNo
'@context': 'https://schema.org',
'@type': 'SoftwareApplication',
name: siteConfig.name,
operatingSystem: 'iOS, Android',
...(operatingSystems.length > 0 && { operatingSystem: operatingSystems.join(', ') }),
applicationCategory: 'LifestyleApplication',
description:
'Pflanzen per Foto erkennen, Pflegepläne nutzen und Pflanzenprobleme einordnen.',
inLanguage: ['en', 'de', 'es'],
description: schemaDescription,
inLanguage: htmlLang,
...(hasIosStoreUrl && { downloadUrl: siteConfig.iosAppStoreUrl }),
offers: {
'@type': 'Offer',
@@ -93,8 +106,7 @@ export default async function RootLayout({ children }: { children: React.ReactNo
'@type': 'Organization',
name: siteConfig.name,
url: siteConfig.domain,
description:
'GreenLens ist eine App zur Pflanzenerkennung und Pflegeplanung für iOS und Android.',
description: organizationDescription,
contactPoint: {
'@type': 'ContactPoint',
contactType: 'customer support',
@@ -109,7 +121,7 @@ export default async function RootLayout({ children }: { children: React.ReactNo
/>
</head>
<body>
<LangProvider>{children}</LangProvider>
<LangProvider initialLang={htmlLang}>{children}</LangProvider>
</body>
</html>
)

View File

@@ -10,6 +10,8 @@ import HowItWorks from '@/components/HowItWorks'
import FAQ from '@/components/FAQ'
import CTA from '@/components/CTA'
import Footer from '@/components/Footer'
import type { Lang } from '@/lib/i18n'
import { getHomeSchemas } from '@/lib/homeSchema'
export const metadata: Metadata = {
title: 'GreenLens - Pflanzen erkennen & Pflege planen',
@@ -26,86 +28,8 @@ export const metadata: Metadata = {
},
}
const howToSchema = {
'@context': 'https://schema.org',
'@type': 'HowTo',
name: 'So erkennst du eine Pflanze mit GreenLens',
step: [
{
'@type': 'HowToStep',
position: 1,
name: 'Pflanze fotografieren',
text: 'Öffne die App, richte die Kamera auf deine Pflanze und tippe auf Scan.',
},
{
'@type': 'HowToStep',
position: 2,
name: 'KI identifiziert sofort',
text: 'In unter einer Sekunde erhältst du den Namen, die Art und die wichtigsten Eckdaten.',
},
{
'@type': 'HowToStep',
position: 3,
name: 'Pflegeplan erhalten',
text: 'GreenLens erstellt automatisch einen Pflegeplan passend zu deiner Pflanze und deinem Standort.',
},
{
'@type': 'HowToStep',
position: 4,
name: 'Wachstum verfolgen',
text: 'Dokumentiere Fotos, verfolge das Gießen und lass dich an wichtige Pflegetermine erinnern.',
},
],
}
const faqSchema = {
'@context': 'https://schema.org',
'@type': 'FAQPage',
mainEntity: [
{
'@type': 'Question',
name: 'Wie erkennt GreenLens eine Pflanze?',
acceptedAnswer: {
'@type': 'Answer',
text: 'GreenLens analysiert das Pflanzenfoto und verbindet das Ergebnis mit Pflegehinweisen in der App, damit du schneller zu klaren nächsten Schritten kommst.',
},
},
{
'@type': 'Question',
name: 'Ist GreenLens kostenlos?',
acceptedAnswer: {
'@type': 'Answer',
text: 'GreenLens bietet kostenlose Funktionen und zusätzlich kostenpflichtige Optionen wie Abos und Credit-Top-ups für erweiterte KI-Funktionen.',
},
},
{
'@type': 'Question',
name: 'Kann ich GreenLens offline nutzen?',
acceptedAnswer: {
'@type': 'Answer',
text: 'Pflanzenidentifikation und Gesundheitscheck benötigen eine Internetverbindung. Deine gespeicherte Sammlung, Pflegenotizen und Gieß-Erinnerungen sind offline verfügbar.',
},
},
{
'@type': 'Question',
name: 'Für welche Pflanzen kann ich GreenLens nutzen?',
acceptedAnswer: {
'@type': 'Answer',
text: 'GreenLens umfasst über 450 Pflanzenarten, darunter Zimmerpflanzen, Gartenpflanzen und Sukkulenten. Die App richtet sich an Pflanzenbesitzer, die Identifikation und Pflege an einem Ort wollen.',
},
},
{
'@type': 'Question',
name: 'Wie starte ich meine Pflanzensammlung?',
acceptedAnswer: {
'@type': 'Answer',
text: 'Starte mit einem Scan, prüfe das Ergebnis und speichere die Pflanze in deiner Sammlung, damit Notizen, Erinnerungen und Pflege an einem Ort bleiben.',
},
},
],
}
export default function Home() {
export default function Home({ locale = 'de' }: { locale?: Lang }) {
const { howTo: howToSchema, faq: faqSchema } = getHomeSchemas(locale)
return (
<>
<script

View File

@@ -8,7 +8,7 @@ export default function sitemap(): MetadataRoute.Sitemap {
return [
{
url: baseUrl,
lastModified: new Date('2026-04-27'),
lastModified: new Date('2026-07-10'),
changeFrequency: 'weekly',
priority: 1,
},
@@ -26,19 +26,19 @@ export default function sitemap(): MetadataRoute.Sitemap {
},
{
url: `${baseUrl}/plant-identifier-app`,
lastModified: new Date('2026-04-27'),
lastModified: new Date('2026-07-10'),
changeFrequency: 'monthly',
priority: 0.8,
},
{
url: `${baseUrl}/plant-disease-identifier`,
lastModified: new Date('2026-04-27'),
lastModified: new Date('2026-07-10'),
changeFrequency: 'monthly',
priority: 0.75,
},
{
url: `${baseUrl}/plant-care-app`,
lastModified: new Date('2026-04-27'),
lastModified: new Date('2026-07-10'),
changeFrequency: 'monthly',
priority: 0.75,
},
@@ -68,43 +68,43 @@ export default function sitemap(): MetadataRoute.Sitemap {
},
{
url: `${baseUrl}/flower-scanner`,
lastModified: new Date('2026-04-27'),
lastModified: new Date('2026-07-10'),
changeFrequency: 'monthly',
priority: 0.8,
},
{
url: `${baseUrl}/identify-plant-photo`,
lastModified: new Date('2026-04-27'),
lastModified: new Date('2026-07-10'),
changeFrequency: 'monthly',
priority: 0.8,
},
{
url: `${baseUrl}/plant-scanner`,
lastModified: new Date('2026-04-27'),
lastModified: new Date('2026-07-10'),
changeFrequency: 'monthly',
priority: 0.8,
},
{
url: `${baseUrl}/houseplant-identifier`,
lastModified: new Date('2026-04-27'),
lastModified: new Date('2026-07-10'),
changeFrequency: 'monthly',
priority: 0.75,
},
{
url: `${baseUrl}/succulent-identifier`,
lastModified: new Date('2026-04-27'),
lastModified: new Date('2026-07-10'),
changeFrequency: 'monthly',
priority: 0.75,
},
{
url: `${baseUrl}/best-plant-identification-app`,
lastModified: new Date('2026-04-27'),
lastModified: new Date('2026-07-10'),
changeFrequency: 'monthly',
priority: 0.85,
},
{
url: `${baseUrl}/plant-health-app`,
lastModified: new Date('2026-04-27'),
lastModified: new Date('2026-07-10'),
changeFrequency: 'monthly',
priority: 0.8,
},
@@ -130,20 +130,20 @@ export default function sitemap(): MetadataRoute.Sitemap {
const profile = getGermanSeoPageBySlug(slug)
return {
url: `${baseUrl}${profile?.canonical ?? `/${slug}`}`,
lastModified: new Date('2026-05-20'),
lastModified: new Date('2026-07-10'),
changeFrequency: 'monthly' as const,
priority: slug === 'pflanzen-erkennen-kostenlos' || slug === 'pflanzen-erkennen-app' ? 0.85 : 0.75,
}
}),
{
url: `${baseUrl}/es`,
lastModified: new Date('2026-05-20'),
lastModified: new Date('2026-07-10'),
changeFrequency: 'monthly',
priority: 0.85,
},
...spanishSeoPageSlugs.map((slug) => ({
url: `${baseUrl}${spanishSeoPageProfiles[slug].canonical}`,
lastModified: new Date('2026-05-20'),
lastModified: new Date('2026-07-10'),
changeFrequency: 'monthly' as const,
priority: slug === 'identificador-de-plantas' ? 0.85 : 0.75,
})),

View File

@@ -9,60 +9,60 @@ const faqs = [
question: {
en: 'How does GreenLens identify a plant?',
de: 'Wie erkennt GreenLens eine Pflanze?',
es: 'Como identifica GreenLens una planta?'
es: '¿Cómo identifica GreenLens una planta?'
},
answer: {
en: 'GreenLens analyzes the plant photo and combines that with app-side care guidance so you can move from scan to next steps faster.',
de: 'GreenLens analysiert das Pflanzenfoto und verbindet das Ergebnis mit Pflegehinweisen in der App, damit du schneller zu klaren nächsten Schritten kommst.',
es: 'GreenLens analiza la foto de la planta y combina el resultado con indicaciones de cuidado dentro de la app para que avances mas rapido.'
es: 'GreenLens analiza la foto de la planta y combina el resultado con indicaciones de cuidado dentro de la app para que avances más rápido.'
}
},
{
question: {
en: 'Is GreenLens free to use?',
de: 'Ist GreenLens kostenlos?',
es: 'Es GreenLens gratuito?'
es: '¿Es GreenLens gratuito?'
},
answer: {
en: 'GreenLens includes free functionality plus paid options such as subscriptions and credit top-ups for advanced AI features.',
de: 'GreenLens bietet kostenlose Funktionen und zusätzlich kostenpflichtige Optionen wie Abos und Credit-Top-ups für erweiterte KI-Funktionen.',
es: 'GreenLens incluye funciones gratuitas y tambien opciones de pago como suscripciones y creditos para funciones de IA mas umfangreiche.'
es: 'GreenLens incluye funciones gratuitas y también opciones de pago como suscripciones y créditos para funciones de IA más amplias.'
}
},
{
question: {
en: 'Can I use GreenLens offline?',
de: 'Kann ich GreenLens offline nutzen?',
es: 'Puedo usar GreenLens sin conexion?'
es: '¿Puedo usar GreenLens sin conexión?'
},
answer: {
en: 'Plant identification and health checks require an internet connection. Your saved collection, care notes, and watering reminders are available offline.',
de: 'Pflanzenidentifikation und Gesundheitscheck benötigen eine Internetverbindung. Deine gespeicherte Sammlung, Pflegenotizen und Gieß-Erinnerungen sind offline verfügbar.',
es: 'La identificacion de plantas y el control de salud requieren conexion a internet. Tu coleccion guardada, notas de cuidado y recordatorios de riego estan disponibles sin conexion.'
es: 'La identificación de plantas y el control de salud requieren conexión a internet. Tu colección guardada, notas de cuidado y recordatorios de riego están disponibles sin conexión.'
}
},
{
question: {
en: 'What kind of plants can I use GreenLens for?',
de: 'Für welche Pflanzen kann ich GreenLens nutzen?',
es: 'Para que tipo de plantas puedo usar GreenLens?'
es: '¿Para qué tipo de plantas puedo usar GreenLens?'
},
answer: {
en: 'GreenLens covers 450+ plant species including houseplants, garden plants, and succulents. It is built for everyday plant owners who want identification and care guidance in one place.',
de: 'GreenLens umfasst über 450 Pflanzenarten, darunter Zimmerpflanzen, Gartenpflanzen und Sukkulenten. Die App richtet sich an Pflanzenbesitzer, die Identifikation und Pflege an einem Ort wollen.',
es: 'GreenLens cubre mas de 450 especies de plantas, incluyendo plantas de interior, de jardin y suculentas. Esta pensada para quienes quieren identificacion y cuidado en un solo lugar.'
es: 'GreenLens cubre más de 450 especies de plantas, incluyendo plantas de interior, de jardín y suculentas. Está pensada para quienes quieren identificación y cuidado en un solo lugar.'
}
},
{
question: {
en: 'How do I start my plant collection?',
de: 'Wie starte ich meine Pflanzensammlung?',
es: 'Como empiezo mi coleccion de plantas?'
es: '¿Cómo empiezo mi colección de plantas?'
},
answer: {
en: 'Start with a scan, review the result, and save the plant to your collection to keep notes, reminders, and follow-up care in one place.',
de: 'Starte mit einem Scan, prüfe das Ergebnis und speichere die Pflanze in deiner Sammlung, damit Notizen, Erinnerungen und Pflege an einem Ort bleiben.',
es: 'Empieza con un escaneo, revisa el resultado y guarda la planta en tu coleccion para mantener notas, recordatorios y cuidado en un solo lugar.'
es: 'Empieza con un escaneo, revisa el resultado y guarda la planta en tu colección para mantener notas, recordatorios y cuidado en un solo lugar.'
}
}
];

View File

@@ -25,24 +25,24 @@ const PILL_KEYS = [
const PILL_TEXT = {
de: [
{ title: 'Smarte Erinnerungen', desc: 'Vergiss nie mehr das Gießen personalisiert für jede Pflanze.' },
{ title: 'Diagnose & Hilfe', desc: 'KI erkennt Krankheiten und Schädlinge sofort.' },
{ title: 'Gesundheitscheck & Hilfe', desc: 'KI ordnet sichtbare Symptome ein und zeigt mögliche nächste Schritte.' },
{ title: 'Standort-Tipps', desc: 'Pflegehinweise basierend auf deinem Klima und Licht.' },
],
en: [
{ title: 'Smart Reminders', desc: 'Never forget watering again personalized for every plant.' },
{ title: 'Diagnosis & Help', desc: 'AI detects diseases and pests instantly.' },
{ title: 'Health Check & Help', desc: 'AI assesses visible symptoms and suggests possible next steps.' },
{ title: 'Location Tips', desc: 'Care advice based on your climate and light conditions.' },
],
es: [
{ title: 'Recordatorios inteligentes', desc: 'Nunca olvides regar personalizado para cada planta.' },
{ title: 'Diagnóstico y ayuda', desc: 'La IA detecta enfermedades y plagas al instante.' },
{ title: 'Chequeo de salud y ayuda', desc: 'La IA evalúa síntomas visibles y propone posibles pasos siguientes.' },
{ title: 'Consejos por ubicación', desc: 'Consejos basados en tu clima y condiciones de luz.' },
],
}
const CARD_TEXT = {
de: {
chip1: 'KI Scan', h3a: 'Scan it.', pa: 'Richte die Kamera auf jede Pflanze GreenLens erkennt sie in Sekundenbruchteilen und liefert alle Infos.',
chip1: 'KI Scan', h3a: 'Scan it.', pa: 'Richte die Kamera auf eine Pflanze GreenLens analysiert das Foto und liefert einen Artvorschlag mit Pflegehinweisen.',
chip2: 'Tracking', h3b: 'Track it.', pb: 'Gießplan, Lichtbedarf und Wachstum alles in einer Timeline.',
chip3: 'Sammlung', h3c: 'Grow it.', pc: 'Baue deine digitale Pflanzenbibliothek auf mit Fotos und Notizen.',
altA: 'Person scannt eine Pflanze mit der GreenLens App',
@@ -50,7 +50,7 @@ const CARD_TEXT = {
altC: 'Pflanzensammlung im Urban Jungle Stil',
},
en: {
chip1: 'AI Scan', h3a: 'Scan it.', pa: 'Point your camera at any plant GreenLens identifies it in milliseconds and delivers all the info.',
chip1: 'AI Scan', h3a: 'Scan it.', pa: 'Point your camera at a plant GreenLens analyzes the photo and returns a suggested match with care guidance.',
chip2: 'Tracking', h3b: 'Track it.', pb: 'Watering schedule, light needs and growth all in one timeline.',
chip3: 'Collection', h3c: 'Grow it.', pc: 'Build your digital plant library with photos and notes.',
altA: 'Person scanning a plant with the GreenLens app',
@@ -58,7 +58,7 @@ const CARD_TEXT = {
altC: 'Plant collection in urban jungle style',
},
es: {
chip1: 'Escaneo IA', h3a: 'Escanéala.', pa: 'Apunta la cámara a cualquier planta GreenLens la identifica en milisegundos y entrega toda la información.',
chip1: 'Escaneo IA', h3a: 'Escanéala.', pa: 'Apunta la cámara a una planta GreenLens analiza la foto y devuelve una coincidencia sugerida con consejos de cuidado.',
chip2: 'Seguimiento', h3b: 'Monitoréala.', pb: 'Plan de riego, necesidades de luz y crecimiento todo en una línea de tiempo.',
chip3: 'Colección', h3c: 'Hazla crecer.', pc: 'Construye tu biblioteca digital de plantas con fotos y notas.',
altA: 'Persona escaneando una planta con la app GreenLens',

View File

@@ -67,7 +67,7 @@ const cards: Record<Lang, GuideCard[]> = {
href: '/plant-identifier-app',
tag: 'Identify',
title: 'Plant Identifier App',
description: 'Scan any plant, get the species instantly, and move straight to care guidance.',
description: 'Scan a plant, review the suggested species, and move straight to care guidance.',
},
{
href: '/identify-plant-photo',
@@ -79,7 +79,7 @@ const cards: Record<Lang, GuideCard[]> = {
href: '/plant-scanner',
tag: 'Scanner',
title: 'Plant Scanner',
description: 'Point your camera at any plant and get name, care plan, and health check.',
description: 'Point your camera at a plant, review the suggested match, and continue with care guidance.',
},
{
href: '/plant-disease-identifier',

View File

@@ -6,19 +6,19 @@ import { useLang } from '@/context/LangContext'
const STEPS = {
de: [
{ num: '01', title: 'Pflanze fotografieren', desc: 'Öffne die App, richte die Kamera auf deine Pflanze und tippe auf Scan. Das war\'s schon.' },
{ num: '02', title: 'KI identifiziert sofort', desc: 'In unter einer Sekunde erhältst du den genauen Namen, die Art und alle wichtigen Eckdaten.' },
{ num: '02', title: 'KI analysiert das Foto', desc: 'Du erhältst zügig einen Artvorschlag und die wichtigsten Eckdaten zur Pflanze.' },
{ num: '03', title: 'Pflegeplan erhalten', desc: 'GreenLens erstellt automatisch einen personalisierten Pflegeplan passend zu deiner Pflanze und deinem Standort.' },
{ num: '04', title: 'Wachstum verfolgen', desc: 'Dokumentiere Fotos, tracke das Gießen und lass dich an wichtige Pflegetermine erinnern.' },
],
en: [
{ num: '01', title: 'Photograph your plant', desc: 'Open the app, point the camera at your plant and tap Scan. That\'s it.' },
{ num: '02', title: 'AI identifies instantly', desc: 'In under a second you get the exact name, species and all key details.' },
{ num: '02', title: 'AI analyzes the photo', desc: 'You quickly receive a suggested match and the key details about the plant.' },
{ num: '03', title: 'Receive care plan', desc: 'GreenLens automatically creates a personalized care plan for your plant and location.' },
{ num: '04', title: 'Track growth', desc: 'Document photos, track watering and get reminded of important care dates.' },
],
es: [
{ num: '01', title: 'Fotografía tu planta', desc: 'Abre la app, apunta la cámara a tu planta y toca Escanear. Eso es todo.' },
{ num: '02', title: 'La IA identifica al instante', desc: 'En menos de un segundo obtienes el nombre exacto, la especie y todos los datos clave.' },
{ num: '02', title: 'La IA analiza la foto', desc: 'Recibes rápidamente una coincidencia sugerida y los datos principales de la planta.' },
{ num: '03', title: 'Recibe el plan de cuidado', desc: 'GreenLens crea automáticamente un plan de cuidado personalizado para tu planta y ubicación.' },
{ num: '04', title: 'Seguimiento del crecimiento', desc: 'Documenta fotos, registra el riego y recibe recordatorios de citas de cuidado importantes.' },
],

View File

@@ -10,8 +10,9 @@ export default function Navbar() {
const [scrolled, setScrolled] = useState(false)
const [menuOpen, setMenuOpen] = useState(false)
const pathname = usePathname()
const { t } = useLang()
const homeHref = (hash: string) => (pathname === '/' ? hash : `/${hash}`)
const { lang, t } = useLang()
const localeHome = lang === 'de' ? '/' : `/${lang}`
const homeHref = (hash: string) => (pathname === localeHome ? hash : `${localeHome}${hash}`)
useEffect(() => {
const onScroll = () => setScrolled(window.scrollY > 40)
@@ -22,7 +23,7 @@ export default function Navbar() {
return (
<nav className={`navbar${scrolled ? ' scrolled' : ''}`} id="navbar" role="navigation" aria-label="Main navigation">
<div className="container">
<Link href="/" className="nav-logo" aria-label="GreenLens Home">
<Link href={localeHome} className="nav-logo" aria-label="GreenLens Home">
GREENLENS
</Link>

View File

@@ -21,6 +21,9 @@ interface SeoCategoryPageProps {
export default function SeoCategoryPage({ profile }: SeoCategoryPageProps) {
const locale = profile.locale ?? 'en'
const copy = seoTemplateCopy[locale]
const templateIntent = profile.templateIntent ?? 'identification'
const usesPhotoAnalysis = templateIntent === 'identification' || templateIntent === 'diagnosis'
const showsCareInsights = templateIntent === 'care' || templateIntent === 'watering'
const faqSchema = {
'@context': 'https://schema.org',
@@ -88,7 +91,7 @@ export default function SeoCategoryPage({ profile }: SeoCategoryPageProps) {
dangerouslySetInnerHTML={{ __html: JSON.stringify(breadcrumbSchema) }}
/>
<SeoNavbar locale={locale} />
<SeoNavbar locale={locale} methodologyHref={usesPhotoAnalysis ? '#methodology' : '#comparison'} />
<main className="pt-[72px] relative overflow-hidden bg-[#fdfbf6]">
{/* Dekorative Farb-Blobs */}
@@ -98,17 +101,21 @@ export default function SeoCategoryPage({ profile }: SeoCategoryPageProps) {
<div className="absolute top-[40%] left-[15%] w-[40vw] h-[40vw] max-w-[500px] max-h-[500px] bg-[#e5f0cb] blur-[100px] rounded-full mix-blend-multiply opacity-70"></div>
</div>
<SeoHero profile={profile} copy={copy} />
<SeoAdvantage profile={profile} copy={copy} />
<SeoMethodology copy={copy} />
<SeoComparison profile={profile} copy={copy} />
<SeoHero
profile={profile}
copy={copy}
secondaryHref={usesPhotoAnalysis ? '#methodology' : '#comparison'}
/>
<SeoAdvantage profile={profile} copy={copy} showInsights={showsCareInsights} />
<SeoContentSections profile={profile} />
{usesPhotoAnalysis && <SeoMethodology copy={copy} intent={templateIntent} />}
<SeoComparison profile={profile} copy={copy} intent={templateIntent} />
<SeoBestFit profile={profile} copy={copy} />
<SeoFaq profile={profile} copy={copy} />
<SeoRelated profile={profile} copy={copy} />
</main>
<SeoFooter locale={locale} />
<SeoFooter locale={locale} showMethodology={usesPhotoAnalysis} />
</div>
)
}

View File

@@ -1,18 +1,23 @@
'use client'
import { useLang } from '@/context/LangContext'
const ITEMS = {
de: [
'Scan it',
'Track it',
'Live Design',
'Urban Jungle',
'Botanical KI',
'Pflege-Tipps',
],
en: ['Scan it', 'Track it', 'Live Design', 'Urban Jungle', 'Botanical AI', 'Care Tips'],
es: ['Escanéala', 'Regístrala', 'Diseño vivo', 'Jardín urbano', 'IA botánica', 'Consejos de cuidado'],
}
export default function Ticker() {
const items = [
'Scan it',
'Track it',
'Live Design',
'Urban Jungle',
'Botanical KI',
'Pflege-Tipps',
'Scan it',
'Track it',
'Live Design',
'Urban Jungle',
'Botanical KI',
'Pflege-Tipps',
]
const { lang } = useLang()
const items = ITEMS[lang]
return (
<div className="ticker-wrap" aria-hidden="true">

View File

@@ -1,12 +1,13 @@
import Link from 'next/link'
import type { Lang } from '@/lib/i18n'
import { englishSeoPageSlugs, germanSeoPageSlugs, getSeoPageBySlug } from '@/lib/seoPages'
import { getSeoPageBySlug } from '@/lib/seoPages'
import { spanishSeoPageProfiles } from '@/lib/spanishSeoPages'
import { seoTemplateCopy } from '@/lib/seoTemplateCopy'
import { siteConfig, hasIosStoreUrl, hasAndroidStoreUrl } from '@/lib/site'
interface SeoFooterProps {
locale: Lang
showMethodology?: boolean
}
function slugLinks(slugs: readonly string[]) {
@@ -16,21 +17,50 @@ function slugLinks(slugs: readonly string[]) {
.map((profile) => ({ href: profile.canonical, label: profile.h1 }))
}
export default function SeoFooter({ locale }: SeoFooterProps) {
const copy = seoTemplateCopy[locale].footer
const primarySlugs: Record<Exclude<Lang, 'es'>, readonly string[]> = {
de: [
'pflanzen-erkennen-app',
'pflanzen-bestimmen',
'pflanzen-krankheiten-erkennen',
'pflanzen-pflege-app',
'giess-erinnerung-app',
'pflanzen-erkennen-kostenlos',
],
en: [
'plant-identifier-app',
'identify-plant-photo',
'plant-disease-identifier',
'plant-care-app',
'plant-health-app',
'best-plant-identification-app',
],
}
const useCaseLinks = [
...slugLinks(englishSeoPageSlugs),
{ href: '/vs/picturethis', label: 'vs PictureThis' },
{ href: '/vs/plantum', label: 'vs Plantum' },
{ href: '/vs/inaturalist', label: 'vs iNaturalist' },
{ href: '/vs/google-lens', label: 'vs Google Lens' },
]
const germanLinks = slugLinks(germanSeoPageSlugs)
const spanishLinks = Object.values(spanishSeoPageProfiles).map((profile) => ({
href: profile.canonical,
label: profile.h1,
}))
const languageHubs = [
{ href: '/', label: 'Deutsch' },
{ href: '/en', label: 'English' },
{ href: '/es', label: 'Español' },
]
const languageTitles: Record<Lang, string> = {
de: 'Sprachen',
en: 'Languages',
es: 'Idiomas',
}
export default function SeoFooter({ locale, showMethodology = true }: SeoFooterProps) {
const copy = seoTemplateCopy[locale].footer
const primaryLinks = locale === 'es'
? Object.values(spanishSeoPageProfiles).map((profile) => ({
href: profile.canonical,
label: profile.h1,
}))
: slugLinks(primarySlugs[locale])
const primaryTitle = locale === 'de'
? copy.germanTitle
: locale === 'es'
? copy.spanishTitle
: copy.useCasesTitle
return (
<footer className="bg-ink-deep text-white pt-24 pb-8 font-body overflow-hidden" id="download">
@@ -95,7 +125,7 @@ export default function SeoFooter({ locale }: SeoFooterProps) {
<h4 className="text-[10px] font-bold tracking-widest text-primary-fixed mb-6 uppercase">{copy.productTitle}</h4>
<ul className="space-y-4 text-xs text-white/80">
<li><a href="#advantage" className="hover:text-white">{seoTemplateCopy[locale].nav.features}</a></li>
<li><a href="#methodology" className="hover:text-white">{seoTemplateCopy[locale].nav.tech}</a></li>
{showMethodology && <li><a href="#methodology" className="hover:text-white">{seoTemplateCopy[locale].nav.tech}</a></li>}
<li><a href="#download" className="hover:text-white">{seoTemplateCopy[locale].nav.download}</a></li>
<li><Link href="/support" className="hover:text-white">{copy.supportLabel}</Link></li>
</ul>
@@ -103,7 +133,7 @@ export default function SeoFooter({ locale }: SeoFooterProps) {
<div>
<h4 className="text-[10px] font-bold tracking-widest text-primary-fixed mb-6 uppercase">{copy.companyTitle}</h4>
<ul className="space-y-4 text-xs text-white/80">
<li><a href="#methodology" className="hover:text-white">{seoTemplateCopy[locale].nav.how}</a></li>
{showMethodology && <li><a href="#methodology" className="hover:text-white">{seoTemplateCopy[locale].nav.how}</a></li>}
<li><a href="#faq" className="hover:text-white">FAQ</a></li>
<li><Link href="/support" className="hover:text-white">{copy.supportLabel}</Link></li>
</ul>
@@ -119,11 +149,11 @@ export default function SeoFooter({ locale }: SeoFooterProps) {
</div>
{/* SEO-Link-Spalten (interne Verlinkung) */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-12 mb-24">
<div className="grid grid-cols-1 md:grid-cols-2 gap-12 mb-24">
<div>
<h4 className="text-[10px] font-bold tracking-widest text-primary-fixed mb-6 uppercase">{copy.useCasesTitle}</h4>
<h4 className="text-[10px] font-bold tracking-widest text-primary-fixed mb-6 uppercase">{primaryTitle}</h4>
<ul className="space-y-3 text-xs text-white/70">
{useCaseLinks.map((link) => (
{primaryLinks.map((link) => (
<li key={link.href}>
<Link href={link.href} className="hover:text-white">{link.label}</Link>
</li>
@@ -131,19 +161,9 @@ export default function SeoFooter({ locale }: SeoFooterProps) {
</ul>
</div>
<div>
<h4 className="text-[10px] font-bold tracking-widest text-primary-fixed mb-6 uppercase">{copy.germanTitle}</h4>
<h4 className="text-[10px] font-bold tracking-widest text-primary-fixed mb-6 uppercase">{languageTitles[locale]}</h4>
<ul className="space-y-3 text-xs text-white/70">
{germanLinks.map((link) => (
<li key={link.href}>
<Link href={link.href} className="hover:text-white">{link.label}</Link>
</li>
))}
</ul>
</div>
<div>
<h4 className="text-[10px] font-bold tracking-widest text-primary-fixed mb-6 uppercase">{copy.spanishTitle}</h4>
<ul className="space-y-3 text-xs text-white/70">
{spanishLinks.map((link) => (
{languageHubs.map((link) => (
<li key={link.href}>
<Link href={link.href} className="hover:text-white">{link.label}</Link>
</li>

View File

@@ -10,17 +10,18 @@ import { seoTemplateCopy } from '@/lib/seoTemplateCopy'
interface SeoNavbarProps {
locale: Lang
methodologyHref?: '#methodology' | '#comparison'
}
export default function SeoNavbar({ locale }: SeoNavbarProps) {
export default function SeoNavbar({ locale, methodologyHref = '#methodology' }: SeoNavbarProps) {
const [menuOpen, setMenuOpen] = useState(false)
const copy = seoTemplateCopy[locale]
const links = [
{ href: '#advantage', label: copy.nav.features },
{ href: '#methodology', label: copy.nav.tech },
{ href: methodologyHref, label: copy.nav.tech },
{ href: '#faq', label: copy.nav.faq },
{ href: '#methodology', label: copy.nav.how },
{ href: methodologyHref, label: copy.nav.how },
{ href: '/support', label: copy.nav.support },
]

View File

@@ -8,7 +8,11 @@ interface SectionProps {
copy: SeoTemplateCopy
}
export function SeoHero({ profile, copy }: SectionProps) {
export function SeoHero({
profile,
copy,
secondaryHref = '#methodology',
}: SectionProps & { secondaryHref?: string }) {
return (
<section className="max-w-[1200px] mx-auto px-6 py-16 grid grid-cols-1 lg:grid-cols-12 gap-12 items-start mt-8">
<div className="lg:col-span-6 z-10 flex flex-col justify-center pt-8">
@@ -29,7 +33,7 @@ export function SeoHero({ profile, copy }: SectionProps) {
</a>
<a
className="inline-flex justify-center items-center px-8 py-3 bg-transparent border-2 border-ink text-ink rounded-full font-bold hover:bg-ink hover:text-white transition-colors duration-300"
href="#methodology"
href={secondaryHref}
>
{copy.hero.ctaSecondary}
</a>
@@ -62,20 +66,30 @@ export function SeoHero({ profile, copy }: SectionProps) {
)
}
export function SeoAdvantage({ profile, copy }: SectionProps) {
export function SeoAdvantage({
profile,
copy,
showInsights = false,
}: SectionProps & { showInsights?: boolean }) {
const reviewedAt = {
de: 'Juli 2026',
en: 'July 2026',
es: 'Julio 2026',
}[profile.locale ?? 'en']
return (
<section className="max-w-[1200px] mx-auto px-6 py-16 grid grid-cols-1 lg:grid-cols-3 gap-12 border-t border-surface-container-high" id="advantage">
<div className="lg:col-span-2">
<section className={`max-w-[1200px] mx-auto px-6 py-16 grid grid-cols-1 ${showInsights ? 'lg:grid-cols-3' : ''} gap-12 border-t border-surface-container-high`} id="advantage">
<div className={showInsights ? 'lg:col-span-2' : ''}>
<div className="mb-8">
<span className="text-xs font-semibold tracking-[0.1em] uppercase text-primary">{copy.advantage.eyebrow}</span>
</div>
<h2 className="font-display font-semibold text-[32px] leading-[1.3] text-primary mb-6">{copy.advantage.heading}</h2>
<p className="font-body text-lg text-on-surface-variant mb-6">{profile.definitionBlock}</p>
<div className="text-xs font-semibold tracking-[0.1em] uppercase text-on-surface-variant">
{copy.advantage.updated}: {profile.lastUpdated}
{copy.advantage.updated}: {reviewedAt}
</div>
</div>
<div className="bg-surface-container rounded-xl p-8 seo-card">
{showInsights && <div className="bg-surface-container rounded-xl p-8 seo-card">
<div className="flex items-center gap-3 mb-6">
<SeoIcon name="psychology" className="w-8 h-8 text-primary" />
<h3 className="font-display font-semibold text-2xl text-primary">{copy.didYouKnow.title}</h3>
@@ -88,22 +102,30 @@ export function SeoAdvantage({ profile, copy }: SectionProps) {
</li>
))}
</ul>
</div>
</div>}
</section>
)
}
export function SeoMethodology({ copy }: { copy: SeoTemplateCopy }) {
export function SeoMethodology({
copy,
intent = 'identification',
}: {
copy: SeoTemplateCopy
intent?: 'identification' | 'diagnosis'
}) {
const methodology = intent === 'diagnosis' ? copy.diagnosisMethodology : copy.methodology
return (
<section className="bg-surface-container-low py-16 md:py-[120px]" id="methodology">
<div className="max-w-[1200px] mx-auto px-6">
<div className="text-center mb-16">
<span className="text-xs font-semibold tracking-[0.1em] uppercase text-primary block mb-4">{copy.methodology.eyebrow}</span>
<h2 className="font-display font-semibold text-[32px] md:text-[40px] leading-[1.2] text-primary">{copy.methodology.title}</h2>
<p className="font-body text-on-surface-variant max-w-2xl mx-auto mt-4">{copy.methodology.lead}</p>
<span className="text-xs font-semibold tracking-[0.1em] uppercase text-primary block mb-4">{methodology.eyebrow}</span>
<h2 className="font-display font-semibold text-[32px] md:text-[40px] leading-[1.2] text-primary">{methodology.title}</h2>
<p className="font-body text-on-surface-variant max-w-2xl mx-auto mt-4">{methodology.lead}</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
{copy.methodology.steps.map((step, index) => (
{methodology.steps.map((step, index) => (
<div key={step.title} className="bg-surface p-8 rounded-xl shadow-sm border border-surface-container-high seo-card">
<div className="w-12 h-12 bg-primary-container text-on-primary-container rounded-full flex items-center justify-center font-display font-semibold text-xl mb-6">
{index + 1}
@@ -120,7 +142,11 @@ export function SeoMethodology({ copy }: { copy: SeoTemplateCopy }) {
const comparisonIcons: SeoIconName[] = ['check_circle', 'calendar', 'healing', 'sun']
export function SeoComparison({ profile, copy }: SectionProps) {
export function SeoComparison({
profile,
copy,
intent = 'identification',
}: SectionProps & { intent?: 'identification' | 'diagnosis' | 'care' | 'watering' }) {
const tipLink = profile.relatedLinks[0]
return (
@@ -130,7 +156,7 @@ export function SeoComparison({ profile, copy }: SectionProps) {
<div className="lg:sticky lg:top-32">
<span className="text-xs font-semibold tracking-[0.1em] uppercase text-primary block mb-4">{copy.comparison.eyebrow}</span>
<h2 className="font-display font-semibold text-[32px] leading-[1.3] text-primary mb-6">{profile.featureTable.title}</h2>
<p className="font-body text-on-surface-variant mb-8">{copy.comparison.lead}</p>
<p className="font-body text-on-surface-variant mb-8">{copy.comparison.intentLead[intent]}</p>
{tipLink && (
<div className="bg-primary-container/20 p-6 rounded-lg border border-primary-container/30">
<h4 className="font-display font-semibold text-base text-primary mb-2">{copy.comparison.tipTitle}</h4>

View File

@@ -15,26 +15,13 @@ const LangContext = createContext<LangCtx>({
t: translations.de,
})
function getInitialLang(): Lang {
if (typeof document === 'undefined') return 'de'
const pathname = window.location.pathname
if (pathname === '/') return 'de'
if (pathname === '/en' || pathname.startsWith('/en/')) return 'en'
if (pathname === '/de' || pathname.startsWith('/de/')) return 'de'
if (pathname === '/es' || pathname.startsWith('/es/')) return 'es'
const match = document.cookie.match(/(?:^|;\s*)lang=([^;]+)/)
const val = match?.[1]
return val === 'en' || val === 'es' || val === 'de' ? val : 'de'
}
export function LangProvider({ children }: { children: ReactNode }) {
const [lang, setLangState] = useState<Lang>('de')
export function LangProvider({ children, initialLang }: { children: ReactNode; initialLang: Lang }) {
const [lang, setLangState] = useState<Lang>(initialLang)
useEffect(() => {
const initialLang = getInitialLang()
document.documentElement.lang = initialLang
setLangState(initialLang)
}, [])
}, [initialLang])
const setLang = (l: Lang) => {
document.cookie = `lang=${l};path=/;max-age=31536000;SameSite=Lax`

View File

@@ -48,7 +48,7 @@ export const competitorProfiles: Record<CompetitorSlug, CompetitorProfile> = {
picturethis: {
slug: 'picturethis',
name: 'PictureThis',
metaTitle: 'GreenLens vs. PictureThis — Honest Plant App Comparison (2026)',
metaTitle: 'GreenLens vs PictureThis: Plant App Comparison (2026)',
metaDescription:
'GreenLens or PictureThis? Compare plant emergency workflows, paywall behavior, care guidance, and diagnosis depth. See which app fits your situation.',
heroSummary:
@@ -208,7 +208,7 @@ export const competitorProfiles: Record<CompetitorSlug, CompetitorProfile> = {
plantum: {
slug: 'plantum',
name: 'Plantum',
metaTitle: 'GreenLens vs. Plantum Plant Triage vs. All-in-One Assistant (2026)',
metaTitle: 'GreenLens vs Plantum: Plant Care Comparison (2026)',
metaDescription:
'GreenLens or Plantum? Compare diagnosis depth, beginner clarity, care workflows, and pricing friction. See which plant app fits your situation.',
heroSummary:
@@ -368,7 +368,7 @@ export const competitorProfiles: Record<CompetitorSlug, CompetitorProfile> = {
inaturalist: {
slug: 'inaturalist',
name: 'iNaturalist',
metaTitle: 'GreenLens vs. iNaturalist Plant Care vs. Citizen Science (2026)',
metaTitle: 'GreenLens vs iNaturalist: Plant App Comparison (2026)',
metaDescription:
'GreenLens or iNaturalist? Plant care, watering reminders, and health diagnosis (GreenLens) vs. biodiversity discovery and community ID (iNaturalist). Find your fit.',
heroSummary:
@@ -401,7 +401,7 @@ export const competitorProfiles: Record<CompetitorSlug, CompetitorProfile> = {
{
title: 'App-first speed vs community dependence',
greenlens:
'GreenLens returns AI-driven results instantly, without waiting for community votes or reviews.',
'GreenLens returns an AI-generated suggestion without waiting for community votes or reviews.',
competitor:
'iNaturalist offers instant AI suggestions at upload, but expert community confirmation — the step that makes an observation Research Grade — can take hours or days. That process works well for research; it is slow for a plant that looks wrong right now.',
},
@@ -417,7 +417,7 @@ export const competitorProfiles: Record<CompetitorSlug, CompetitorProfile> = {
{
title: 'Plant identification',
greenlens:
'AI-powered scan results in seconds. Accurate enough for the 450+ common species most plant owners encounter.',
'AI-powered scanning provides a suggested match from a catalog covering more than 450 common species; users should review the result before following care guidance.',
competitor:
'Strong and often highly accurate, especially for unusual or rare species. Community input adds credibility over time.',
whyItMatters:

View File

@@ -0,0 +1,84 @@
import type { Lang } from '@/lib/i18n'
const schemaCopy: Record<Lang, {
howToName: string
steps: Array<{ name: string; text: string }>
faqs: Array<{ question: string; answer: string }>
}> = {
de: {
howToName: 'So erkennst du eine Pflanze mit GreenLens',
steps: [
{ name: 'Pflanze fotografieren', text: 'Öffne die App, richte die Kamera auf deine Pflanze und tippe auf Scan. Das war\'s schon.' },
{ name: 'KI analysiert das Foto', text: 'Du erhältst zügig einen Artvorschlag und die wichtigsten Eckdaten zur Pflanze.' },
{ name: 'Pflegeplan erhalten', text: 'GreenLens erstellt automatisch einen personalisierten Pflegeplan passend zu deiner Pflanze und deinem Standort.' },
{ name: 'Wachstum verfolgen', text: 'Dokumentiere Fotos, tracke das Gießen und lass dich an wichtige Pflegetermine erinnern.' },
],
faqs: [
{ question: 'Wie erkennt GreenLens eine Pflanze?', answer: 'GreenLens analysiert das Pflanzenfoto und verbindet das Ergebnis mit Pflegehinweisen in der App, damit du schneller zu klaren nächsten Schritten kommst.' },
{ question: 'Ist GreenLens kostenlos?', answer: 'GreenLens bietet kostenlose Funktionen und zusätzlich kostenpflichtige Optionen wie Abos und Credit-Top-ups für erweiterte KI-Funktionen.' },
{ question: 'Kann ich GreenLens offline nutzen?', answer: 'Pflanzenidentifikation und Gesundheitscheck benötigen eine Internetverbindung. Deine gespeicherte Sammlung, Pflegenotizen und Gieß-Erinnerungen sind offline verfügbar.' },
{ question: 'Für welche Pflanzen kann ich GreenLens nutzen?', answer: 'GreenLens umfasst über 450 Pflanzenarten, darunter Zimmerpflanzen, Gartenpflanzen und Sukkulenten. Die App richtet sich an Pflanzenbesitzer, die Identifikation und Pflege an einem Ort wollen.' },
{ question: 'Wie starte ich meine Pflanzensammlung?', answer: 'Starte mit einem Scan, prüfe das Ergebnis und speichere die Pflanze in deiner Sammlung, damit Notizen, Erinnerungen und Pflege an einem Ort bleiben.' },
],
},
en: {
howToName: 'How to identify a plant with GreenLens',
steps: [
{ name: 'Photograph your plant', text: 'Open the app, point the camera at your plant and tap Scan. That\'s it.' },
{ name: 'AI analyzes the photo', text: 'You quickly receive a suggested match and the key details about the plant.' },
{ name: 'Receive care plan', text: 'GreenLens automatically creates a personalized care plan for your plant and location.' },
{ name: 'Track growth', text: 'Document photos, track watering, and get reminded of important care dates.' },
],
faqs: [
{ question: 'How does GreenLens identify a plant?', answer: 'GreenLens analyzes the plant photo and combines that with app-side care guidance so you can move from scan to next steps faster.' },
{ question: 'Is GreenLens free to use?', answer: 'GreenLens includes free functionality plus paid options such as subscriptions and credit top-ups for advanced AI features.' },
{ question: 'Can I use GreenLens offline?', answer: 'Plant identification and health checks require an internet connection. Your saved collection, care notes, and watering reminders are available offline.' },
{ question: 'What kind of plants can I use GreenLens for?', answer: 'GreenLens covers 450+ plant species including houseplants, garden plants, and succulents. It is built for everyday plant owners who want identification and care guidance in one place.' },
{ question: 'How do I start my plant collection?', answer: 'Start with a scan, review the result, and save the plant to your collection to keep notes, reminders, and follow-up care in one place.' },
],
},
es: {
howToName: 'Cómo identificar una planta con GreenLens',
steps: [
{ name: 'Fotografía tu planta', text: 'Abre la app, apunta la cámara a tu planta y toca Escanear. Eso es todo.' },
{ name: 'La IA analiza la foto', text: 'Recibes rápidamente una coincidencia sugerida y los datos principales de la planta.' },
{ name: 'Recibe el plan de cuidado', text: 'GreenLens crea automáticamente un plan de cuidado personalizado para tu planta y ubicación.' },
{ name: 'Seguimiento del crecimiento', text: 'Documenta fotos, registra el riego y recibe recordatorios de citas de cuidado importantes.' },
],
faqs: [
{ question: '¿Cómo identifica GreenLens una planta?', answer: 'GreenLens analiza la foto de la planta y combina el resultado con indicaciones de cuidado dentro de la app para que avances más rápido.' },
{ question: '¿Es GreenLens gratuito?', answer: 'GreenLens incluye funciones gratuitas y también opciones de pago como suscripciones y créditos para funciones de IA más amplias.' },
{ question: '¿Puedo usar GreenLens sin conexión?', answer: 'La identificación de plantas y el control de salud requieren conexión a internet. Tu colección guardada, notas de cuidado y recordatorios de riego están disponibles sin conexión.' },
{ question: '¿Para qué tipo de plantas puedo usar GreenLens?', answer: 'GreenLens cubre más de 450 especies de plantas, incluyendo plantas de interior, de jardín y suculentas. Está pensada para quienes quieren identificación y cuidado en un solo lugar.' },
{ question: '¿Cómo empiezo mi colección de plantas?', answer: 'Empieza con un escaneo, revisa el resultado y guarda la planta en tu colección para mantener notas, recordatorios y cuidado en un solo lugar.' },
],
},
}
export function getHomeSchemas(locale: Lang) {
const copy = schemaCopy[locale]
return {
howTo: {
'@context': 'https://schema.org',
'@type': 'HowTo',
name: copy.howToName,
inLanguage: locale,
step: copy.steps.map((step, index) => ({
'@type': 'HowToStep',
position: index + 1,
...step,
})),
},
faq: {
'@context': 'https://schema.org',
'@type': 'FAQPage',
inLanguage: locale,
mainEntity: copy.faqs.map(({ question, answer }) => ({
'@type': 'Question',
name: question,
acceptedAnswer: { '@type': 'Answer', text: answer },
})),
},
}
}

View File

@@ -136,66 +136,66 @@ export const translations = {
es: {
nav: {
features: 'Funciones',
tech: 'Tecnologia',
how: 'Como funciona',
tech: 'Tecnología',
how: 'Cómo funciona',
download: 'Descargar',
cta: 'Empezar',
},
hero: {
eyebrow: 'GreenLens App - Inteligencia botanica',
h1a: 'Tu jardin',
eyebrow: 'GreenLens App - Inteligencia botánica',
h1a: 'Tu jardín',
h1b: 'urbano,',
h1em: 'mejor cuidado.',
desc: 'Escanea plantas, entiende lo que necesitan y organiza cuidado, recordatorios y coleccion en una sola app.',
desc: 'Escanea plantas, entiende lo que necesitan y organiza cuidados, recordatorios y tu colección en una sola app.',
primary: 'Explorar la app',
secondary: 'Saber mas',
badge: 'Plant care with AI',
segTitle: 'En que te ayuda GreenLens?',
secondary: 'Saber más',
badge: 'Cuidado de plantas con IA',
segTitle: '¿En qué te ayuda GreenLens?',
segOpt1: 'Quiero identificar la planta.',
segOpt2: 'Quiero entender problemas de cuidado.',
},
brownLeaf: {
tag: 'Ayuda para plantas',
headline: 'Menos adivinanzas.',
sub: 'Entiende mas rapido que puede necesitar tu planta.',
desc: 'GreenLens te ayuda a interpretar sintomas, identificar plantas y obtener pasos de cuidado mas claros.',
sub: 'Entiende más rápido qué puede necesitar tu planta.',
desc: 'GreenLens te ayuda a interpretar síntomas, identificar plantas y obtener pasos de cuidado más claros.',
before: 'Antes',
after: 'Despues',
sliderLabel: 'Comparador antes y despues',
after: 'Después',
sliderLabel: 'Comparador antes y después',
proof1title: 'Evaluar puntas marrones',
proof1desc: 'Pasa de la duda a una causa mas clara',
proof1desc: 'Pasa de la duda a una causa más clara',
proof2title: 'Ordenar la rutina',
proof2desc: 'Menos caos con luz, riego e intervalos',
proof3title: 'Guardar ayuda en un lugar',
proof3desc: 'Escaneo, coleccion y notas juntos',
proof3desc: 'Escaneo, colección y notas juntos',
},
features: {
tag: 'Funciones',
h2a: 'Todo lo que tu',
h2b: 'jardin urbano necesita.',
desc: 'Desde la primera identificacion hasta el cuidado continuo, GreenLens te ayuda a entender mejor tus plantas y a organizarte. El lexico cubre mas de 450 especies de plantas.',
h2b: 'jardín urbano necesita.',
desc: 'Desde la primera identificación hasta el cuidado continuo, GreenLens te ayuda a entender mejor tus plantas y a organizarte. El catálogo cubre cientos de especies.',
},
cta: {
tag: 'Descarga',
h2a: 'Listo para un mejor',
h2a: '¿Listo para un mejor',
h2em: 'cuidado de plantas?',
desc: 'GreenLens te ayuda a identificar, entender y cuidar tus plantas. Si la ficha de la tienda aun no esta activa, usa la pagina de soporte.',
desc: 'GreenLens te ayuda a identificar, entender y cuidar tus plantas. Si la ficha de la tienda aún no está activa, usa la página de soporte.',
apple: 'Descargar en',
google: 'Disponible en',
support: 'Abrir',
supportLabel: 'Soporte',
contact: 'Contacto',
email: 'Enviar correo',
comingSoon: 'La app estara disponible pronto.',
liveNote: 'La app ya esta disponible en las tiendas.',
comingSoon: 'La app estará disponible pronto.',
liveNote: 'La app ya está disponible en las tiendas.',
},
footer: {
brand: 'La app para quienes quieren identificacion, cuidado y coleccion de plantas en un solo lugar.',
brand: 'La app para quienes quieren identificación, cuidado y colección de plantas en un solo lugar.',
copy: '© 2026 GreenLens. Todos los derechos reservados.',
cols: [
{ title: 'Producto', links: ['Funciones', 'Tecnologia', 'Descargar', 'Support'] },
{ title: 'Recursos', links: ['Como funciona', 'FAQ', 'Support'] },
{ title: 'Legal', links: ['Aviso legal', 'Privacidad', 'Terminos del servicio'] },
{ title: 'Producto', links: ['Funciones', 'Tecnología', 'Descargar', 'Soporte'] },
{ title: 'Recursos', links: ['Cómo funciona', 'FAQ', 'Soporte'] },
{ title: 'Legal', links: ['Aviso legal', 'Privacidad', 'Términos del servicio'] },
],
},
},

View File

@@ -25,6 +25,8 @@ export interface SeoContentSection {
export interface SeoPageProfile {
slug: string
locale?: 'en' | 'de' | 'es'
/** Controls which shared template sections fit the page's search intent. */
templateIntent?: 'identification' | 'diagnosis' | 'care' | 'watering'
metaTitle: string
metaDescription: string
canonical: string
@@ -51,12 +53,12 @@ const seoPageProfiles: Record<string, SeoPageProfile> = {
slug: 'plant-identifier-app',
metaTitle: 'Plant Identifier App — GreenLens',
metaDescription:
'GreenLens is a plant identifier app that goes beyond the name. Scan any plant, get the species instantly, and move straight to care guidance, health checks, and rescue decisions.',
'GreenLens is a plant identifier app that goes beyond the name. Scan a plant, review the suggested match, and move straight to care guidance and health checks.',
canonical: '/plant-identifier-app',
h1: 'Plant Identifier App',
tagline: 'Identify any plant in seconds — then know exactly what to do next.',
tagline: 'Scan a plant, review the suggested match, and understand the next care steps.',
directAnswer:
'GreenLens is a plant identifier app for iOS and Android. Point your camera at any plant, tap Scan, and receive the species name, care requirements, and next-step guidance in under a second.',
'GreenLens is a plant identifier app for iOS and Android. Point your camera at a plant, tap Scan, and quickly receive the species name, care requirements, and next-step guidance.',
definitionBlock:
'A plant identifier app uses your phone camera and AI to match a photo against a plant database and return the species name, common names, and care profile. GreenLens extends this with health diagnostics and care scheduling so identification leads directly to action.',
lastUpdated: 'April 2026',
@@ -67,7 +69,7 @@ const seoPageProfiles: Record<string, SeoPageProfile> = {
rows: [
{
feature: 'Instant plant identification',
greenlens: 'AI scan returns species name, common names, and plant profile in under a second.',
greenlens: 'AI scan quickly returns the species name, common names, and plant profile.',
alternative: 'Most apps return a species name and stop there.',
},
{
@@ -105,7 +107,7 @@ const seoPageProfiles: Record<string, SeoPageProfile> = {
{
question: 'How accurate is GreenLens for plant identification?',
answer:
'GreenLens accurately identifies 450+ plant species including the most common houseplants, garden plants, and succulents. For rare or highly regional species, community platforms such as iNaturalist may have a broader expert pool. For everyday owned plants, GreenLens is fast and reliable.',
'The GreenLens catalog covers more than 450 plant species, including common houseplants, garden plants, and succulents. Results depend on image quality and how distinctive the plant is, so review the suggested match before acting on it. For rare or highly regional species, community platforms such as iNaturalist may offer a broader expert pool.',
},
{
question: 'Does GreenLens work offline?',
@@ -159,6 +161,7 @@ const seoPageProfiles: Record<string, SeoPageProfile> = {
'plant-disease-identifier': {
slug: 'plant-disease-identifier',
templateIntent: 'diagnosis',
metaTitle: 'Plant Disease Identifier — GreenLens',
metaDescription:
'Use GreenLens to identify plant diseases from visible symptoms. Get a concrete next action — not a list of possibilities — when your plant shows yellow leaves, soft stems, or sudden decline.',
@@ -254,6 +257,7 @@ const seoPageProfiles: Record<string, SeoPageProfile> = {
'plant-care-app': {
slug: 'plant-care-app',
templateIntent: 'care',
metaTitle: 'Plant Care App — GreenLens',
metaDescription:
'GreenLens is a plant care app that goes beyond simple watering reminders. It connects care decisions to what your plant actually needs — not to a generic calendar.',
@@ -368,7 +372,7 @@ const seoPageProfiles: Record<string, SeoPageProfile> = {
rows: [
{
feature: 'Pflanzenerkennung per Foto',
greenlens: 'KI-gestützter Scan liefert Artname, Trivialname und Pflanzenportrait in unter einer Sekunde.',
greenlens: 'Der KI-gestützte Scan liefert einen Artvorschlag mit Trivialname und Pflanzenportrait.',
alternative: 'Artname wird ausgegeben — ohne weitere Informationen oder nächste Schritte.',
},
{
@@ -497,7 +501,7 @@ const additionalSeoPages: Record<string, SeoPageProfile> = {
{
feature: 'Blumen- und Pflanzenerkennung',
greenlens:
'KI-gestützter Scan erkennt Blumen und Pflanzen in unter einer Sekunde — mit Artname, Trivialname und botanischer Einordnung.',
'Der KI-gestützte Scan liefert für Blumen und Pflanzen einen Artvorschlag mit Trivialname und botanischer Einordnung.',
alternative:
'Name wird ausgegeben. Weitere Informationen fehlen oder sind hinter einer Paywall.',
},
@@ -575,7 +579,7 @@ const additionalSeoPages: Record<string, SeoPageProfile> = {
{
question: 'Was ist das für eine Pflanze? Wie finde ich es mit dem Handy heraus?',
answer:
'Mit GreenLens genügt ein Foto: App öffnen, Kamera auf die Pflanze oder Blume richten und scannen. In unter einer Sekunde erscheinen Artname, Pflanzenportrait und ein vollständiger Pflegeplan. Alternativ kannst du eine Blume per Foto erkennen, indem du ein Bild aus der Galerie hochlädst.',
'Mit GreenLens genügt ein klares Foto: App öffnen, Kamera auf die Pflanze oder Blume richten und scannen. Anschließend kannst du den Artvorschlag prüfen und das Pflanzenportrait mit Pflegehinweisen öffnen. Alternativ lässt sich ein Bild aus der Galerie hochladen.',
},
{
question: 'Was ist der Unterschied zwischen Blumenscanner und Blumen bestimmen App?',
@@ -659,7 +663,7 @@ const additionalSeoPages: Record<string, SeoPageProfile> = {
{
feature: 'Bestimmung per Foto',
greenlens:
'KI-gestützter Scan liefert Artname und vollständiges Pflanzenportrait in unter einer Sekunde.',
'Der KI-gestützte Scan liefert einen Artvorschlag und das zugehörige Pflanzenportrait.',
alternative:
'Google Lens erkennt Pflanzen und zeigt Links zu Google-Suchergebnissen.',
},
@@ -706,7 +710,7 @@ const additionalSeoPages: Record<string, SeoPageProfile> = {
{
question: 'Wie kann ich eine Pflanze per Foto bestimmen?',
answer:
'Mit GreenLens: App öffnen, Kamera auf die Pflanze richten, scannen. In unter einer Sekunde erscheinen Artname, botanische Klassifizierung und ein vollständiger Pflegeplan. Alternativ kannst du ein Foto aus der Galerie hochladen, wenn du die Pflanze später bestimmen möchtest.',
'Mit GreenLens: App öffnen, Kamera auf die Pflanze richten und scannen. Danach prüfst du den Artvorschlag, die botanische Einordnung und die passenden Pflegehinweise. Alternativ kannst du ein Foto aus der Galerie hochladen.',
},
{
question: 'Kann ich Pflanzen per Foto kostenlos bestimmen?',
@@ -772,14 +776,14 @@ const additionalSeoPages: Record<string, SeoPageProfile> = {
const englishSeoPages: Record<string, SeoPageProfile> = {
'flower-scanner': {
slug: 'flower-scanner',
metaTitle: 'Flower Scanner App Identify Any Flower by Photo Instantly | GreenLens',
metaTitle: 'Flower Scanner: Identify Flowers by Photo | GreenLens',
metaDescription:
'Point your camera at any flower and get the name instantly — plus a care plan, watering reminders, and health diagnosis. Free to start, no paywall at the scan.',
'Photograph a flower, review the suggested match, and continue with care guidance, watering reminders, and an optional health check.',
canonical: '/flower-scanner',
h1: 'Flower Scanner',
tagline: 'Photograph a flower — get the name, origin, and care plan instantly.',
tagline: 'Photograph a flower, review the suggested match, and continue with a care plan.',
directAnswer:
'GreenLens is a flower scanner for iOS and Android. Point your camera at any flower or plant, tap Scan, and receive the species name, botanical classification, and a complete care plan in under a second.',
'GreenLens is a flower scanner for iOS and Android. Point your camera at a flower or plant, tap Scan, and quickly receive the species name, botanical classification, and a care plan.',
definitionBlock:
'A flower scanner identifies flowers and plants from photos and returns the species name along with care information. GreenLens goes beyond simple name lookup: every scan automatically generates a care plan, and a separate health check analyzes symptoms like wilting blooms, yellowing leaves, or pest damage.',
lastUpdated: 'April 2026',
@@ -791,7 +795,7 @@ const englishSeoPages: Record<string, SeoPageProfile> = {
{
feature: 'Flower and plant recognition',
greenlens:
'AI-powered scan identifies flowers and plants in under a second — species name, common name, and botanical classification.',
'AI-powered scanning quickly identifies flowers and plants and returns the species name, common name, and botanical classification.',
alternative:
'Returns a name. Further information is missing or locked behind a paywall.',
},
@@ -823,7 +827,7 @@ const englishSeoPages: Record<string, SeoPageProfile> = {
],
},
greenLensIf: [
'You want to identify a flower or plant instantly and know right away how to care for it.',
'You want to identify a flower or plant and move directly to practical care guidance.',
'You have a flower that is wilting or showing symptoms and need a concrete diagnosis.',
'You want to manage a collection of your flowers and plants with care reminders.',
],
@@ -835,7 +839,7 @@ const englishSeoPages: Record<string, SeoPageProfile> = {
{
question: 'What flower is this? How do I find out using my phone?',
answer:
'With GreenLens: open the app, point the camera at the flower or plant, and tap Scan. In under a second you get the species name, plant portrait, and a complete care plan. You can also upload a photo from your gallery instead of taking a new shot.',
'With GreenLens: open the app, point the camera at the flower or plant, and tap Scan. You quickly get the species name, plant portrait, and a care plan. You can also upload a photo from your gallery instead of taking a new shot.',
},
{
question: 'Can GreenLens identify both flowers and houseplants?',
@@ -862,7 +866,7 @@ const englishSeoPages: Record<string, SeoPageProfile> = {
{
href: '/plant-identifier-app',
label: 'Plant Identifier App',
description: 'Identify any plant species — with care plan, diagnosis, and collection.',
description: 'Identify supported plant species and connect the suggested match with care guidance and your collection.',
},
{
href: '/identify-plant-photo',
@@ -898,7 +902,7 @@ const englishSeoPages: Record<string, SeoPageProfile> = {
{
feature: 'Identification by photo',
greenlens:
'AI scan returns species name and full plant portrait in under a second.',
'AI scanning quickly returns the species name and full plant portrait.',
alternative:
'Google Lens identifies plants and shows links to Google search results.',
},
@@ -1011,7 +1015,7 @@ const englishSeoPages: Record<string, SeoPageProfile> = {
{
href: '/flower-scanner',
label: 'Flower Scanner',
description: 'Scan flowers by photo — species name, origin, and care plan instantly.',
description: 'Scan flowers by photo, review the suggested species, and continue with care guidance.',
},
{
href: '/vs/google-lens',
@@ -1026,7 +1030,8 @@ const germanSeoPages2: Record<string, SeoPageProfile> = {
'pflanzen-krankheiten-erkennen': {
slug: 'pflanzen-krankheiten-erkennen',
locale: 'de',
metaTitle: 'Pflanzenkrankheiten erkennen & diagnostizieren per Foto | GreenLens',
templateIntent: 'diagnosis',
metaTitle: 'Pflanzenkrankheiten per Foto erkennen | GreenLens',
metaDescription:
'Pflanzenkrankheit erkennen: gelbe Blätter, braune Flecken, Schädlinge oder Wurzelfäule per Foto analysieren und sofort den nächsten richtigen Schritt erhalten.',
canonical: '/pflanzen-krankheiten-erkennen',
@@ -1147,6 +1152,7 @@ const germanSeoPages2: Record<string, SeoPageProfile> = {
'pflanzen-pflege-app': {
slug: 'pflanzen-pflege-app',
locale: 'de',
templateIntent: 'care',
metaTitle: 'Pflanzen Pflege App: Pflegeplan pro Pflanze | GreenLens',
metaDescription:
'Pflegeplan, Gießerinnerung und Push-Hinweise pro Pflanze: Die GreenLens Pflanzen Pflege App hilft bei Standort, Licht, Wasser und Diagnose.',
@@ -1307,6 +1313,7 @@ const germanSeoPages2: Record<string, SeoPageProfile> = {
'giess-erinnerung-app': {
slug: 'giess-erinnerung-app',
locale: 'de',
templateIntent: 'watering',
metaTitle: 'Gieß-Erinnerung App: Pflanzen gießen Erinnerung | GreenLens',
metaDescription:
'Nie wieder Gießen vergessen: GreenLens erinnert dich pro Pflanze ans Gießen — mit Gießplan nach Pflanzenart, Standort und Jahreszeit. Kostenlos starten.',
@@ -1428,7 +1435,7 @@ const germanSeoPages2: Record<string, SeoPageProfile> = {
{
question: 'Hilft die App auch gegen Überwässerung?',
answer:
'Ja. Überwässerung ist die häufigste Todesursache bei Zimmerpflanzen. Zeigt eine Pflanze weiche Stiele oder gelbe Blätter, erkennt der GreenLens-Gesundheitscheck Überwässerung und empfiehlt eine Gießpause, statt weiter zu erinnern.',
'Ja. Zu häufiges Gießen und dauerhaft nasse Erde können Zimmerpflanzen schädigen. Zeigt eine Pflanze weiche Stiele oder gelbe Blätter, kann der GreenLens-Gesundheitscheck mögliche Anzeichen von Überwässerung einordnen und eine Gießpause vorschlagen.',
},
{
question: 'Funktioniert die Gieß-Erinnerung auch für Balkon- und Gartenpflanzen?',
@@ -1487,7 +1494,7 @@ const germanSeoPages2: Record<string, SeoPageProfile> = {
{
feature: 'Zimmerpflanzenerkennung',
greenlens:
'KI-Scan erkennt häufige Zimmerpflanzen Monstera, Pothos, Ficus, Orchideen, Sukkulenten — in unter einer Sekunde.',
'Der KI-Scan ist auf häufige Zimmerpflanzen wie Monstera, Pothos, Ficus, Orchideen und Sukkulenten ausgelegt.',
alternative:
'Allgemeine Bild-Suche liefert Namen und Links — ohne pflanzenspezifische Pflegehinweise.',
},
@@ -1605,14 +1612,14 @@ const germanSeoPages2: Record<string, SeoPageProfile> = {
const englishSeoPages2: Record<string, SeoPageProfile> = {
'plant-scanner': {
slug: 'plant-scanner',
metaTitle: 'Plant Scanner App — Scan Any Plant for Instant ID and Care | GreenLens',
metaTitle: 'Plant Scanner: Plant ID and Care | GreenLens',
metaDescription:
'GreenLens is the plant scanner that goes further: scan any plant with your camera, get the species name instantly, then receive a full care plan and health diagnosis.',
'GreenLens is a plant scanner that goes further: scan a plant, review the suggested match, then receive care guidance and an optional health check.',
canonical: '/plant-scanner',
h1: 'Plant Scanner',
tagline: 'Point. Scan. Know the plant, the care, and the next step — in under a second.',
tagline: 'Point. Scan. Quickly learn the plant, its care, and the next step.',
directAnswer:
'GreenLens is a plant scanner for iOS and Android. Point your camera at any plant, tap Scan, and get the species name, care requirements, and next-step guidance in under a second. Unlike basic scanners, it keeps going after the name.',
'GreenLens is a plant scanner for iOS and Android. Point your camera at a plant, tap Scan, and quickly get the species name, care requirements, and next-step guidance. Unlike basic scanners, it keeps going after the name.',
definitionBlock:
'A plant scanner uses your phone camera and AI to identify plants from photos and return the species name. GreenLens extends scanning with an automatic care plan, context-aware watering reminders, and a health check tool — so a scan leads to action, not just a label.',
lastUpdated: 'April 2026',
@@ -1624,7 +1631,7 @@ const englishSeoPages2: Record<string, SeoPageProfile> = {
{
feature: 'Instant plant scan',
greenlens:
'AI scan returns species name, common name, and plant profile in under a second.',
'AI scanning quickly returns the species name, common name, and plant profile.',
alternative:
'Returns a species name and stops there.',
},
@@ -1671,7 +1678,7 @@ const englishSeoPages2: Record<string, SeoPageProfile> = {
{
question: 'How does GreenLens scan plants?',
answer:
'Open the app, point the camera at the plant, and tap Scan. GreenLens uses AI to match the image against a database of 450+ species and returns the species name, plant profile, and care plan in under a second. You can also upload a photo from your gallery.',
'Open the app, point the camera at the plant, and tap Scan. GreenLens uses AI to match the image against its plant database and quickly returns the species name, plant profile, and care plan. You can also upload a photo from your gallery.',
},
{
question: 'Is GreenLens free to use as a plant scanner?',
@@ -1686,7 +1693,7 @@ const englishSeoPages2: Record<string, SeoPageProfile> = {
{
question: 'How accurate is the GreenLens plant scanner?',
answer:
'GreenLens accurately identifies 450+ plant species including the most common houseplants, garden plants, and succulents. For rare or regionally specific species, iNaturalist has a broader expert community. For everyday plants, GreenLens is fast and reliable.',
'The GreenLens catalog covers more than 450 plant species, including common houseplants, garden plants, and succulents. Match quality depends on the photo and the plant, so review the suggestion before using its care guidance. For rare or regionally specific species, iNaturalist has a broader expert community.',
},
{
question: 'What happens after GreenLens scans a plant?',
@@ -1715,14 +1722,14 @@ const englishSeoPages2: Record<string, SeoPageProfile> = {
'houseplant-identifier': {
slug: 'houseplant-identifier',
metaTitle: 'Houseplant Identifier — Identify Any Indoor Plant by Photo | GreenLens',
metaTitle: 'Houseplant Identifier by Photo | GreenLens',
metaDescription:
'GreenLens identifies houseplants by photo in seconds. Get the species name, indoor care plan, watering reminders, and health diagnosis — all in one app.',
'GreenLens assesses houseplants by photo and combines the suggested match with an indoor care plan, watering reminders, and an optional health check.',
canonical: '/houseplant-identifier',
h1: 'Houseplant Identifier',
tagline: 'Photograph any houseplant — get the name, indoor care guide, and watering schedule instantly.',
tagline: 'Photograph a houseplant, review the suggested match, and get an indoor care guide.',
directAnswer:
'GreenLens is a houseplant identifier for iOS and Android. Scan any indoor plant to get the species name and an indoor-specific care plan including watering frequency, light requirements, and fertilizing schedule — in under a second.',
'GreenLens is a houseplant identifier for iOS and Android. Scan an indoor plant to quickly get the species name and an indoor-specific care plan, including watering frequency, light requirements, and a fertilizing schedule.',
definitionBlock:
'A houseplant identifier uses a photo to determine the species and care requirements of an indoor plant. GreenLens is built specifically for plant owners: every identification automatically generates a care plan tailored to indoor conditions, and a health check helps diagnose problems like yellow leaves, root rot signs, or pest damage.',
lastUpdated: 'April 2026',
@@ -1734,7 +1741,7 @@ const englishSeoPages2: Record<string, SeoPageProfile> = {
{
feature: 'Houseplant identification',
greenlens:
'Identifies 450+ species including Monstera, Pothos, Ficus, orchids, succulents, snake plants, and more — in under a second.',
'Quickly identifies common houseplants such as Monstera, Pothos, Ficus, orchids, succulents, and snake plants.',
alternative:
'Returns a species name without further context or next steps.',
},
@@ -1808,7 +1815,7 @@ const englishSeoPages2: Record<string, SeoPageProfile> = {
{
href: '/plant-identifier-app',
label: 'Plant Identifier App',
description: 'Identify any plant species — indoors or outdoors — with care plan and diagnosis.',
description: 'Identify supported indoor and outdoor plants and continue with care guidance and an optional health check.',
},
{
href: '/plant-care-app',
@@ -1825,14 +1832,14 @@ const englishSeoPages2: Record<string, SeoPageProfile> = {
'succulent-identifier': {
slug: 'succulent-identifier',
metaTitle: 'Succulent Identifier — Identify Any Succulent by Photo | GreenLens',
metaTitle: 'Succulent Identifier by Photo | GreenLens',
metaDescription:
'GreenLens identifies succulents and cacti by photo in seconds. Get the species name, watering schedule, light requirements, and a health check — all in one app.',
'GreenLens assesses succulents and cacti by photo and combines the suggested match with watering, light, and care guidance.',
canonical: '/succulent-identifier',
h1: 'Succulent Identifier',
tagline: 'Photograph any succulent — species name, watering schedule, and care plan instantly.',
tagline: 'Photograph a succulent, review the suggested match, and get tailored care guidance.',
directAnswer:
'GreenLens identifies succulents and cacti by photo in under a second. The app returns the species name with a care plan specifically adapted for succulents including low-frequency watering schedules, light requirements, and soil conditions.',
'GreenLens quickly identifies succulents and cacti by photo. The app returns the species name with a care plan adapted for succulents, including watering schedules, light requirements, and soil conditions.',
definitionBlock:
'A succulent identifier uses a photo to determine the species of a succulent or cactus and provide relevant care information. Succulents have specific needs — infrequent watering, bright indirect light, fast-draining soil — that generic plant apps often get wrong. GreenLens generates care plans tuned to succulent requirements after every scan.',
lastUpdated: 'April 2026',
@@ -1891,7 +1898,7 @@ const englishSeoPages2: Record<string, SeoPageProfile> = {
{
question: 'How do I identify a succulent from a photo?',
answer:
'Open GreenLens, point the camera at the succulent, and tap Scan. The app identifies the succulent species in under a second and generates a care plan specific to that genus including the recommended watering frequency, light conditions, and soil type. You can also upload a photo from your gallery.',
'Open GreenLens, point the camera at the succulent, and tap Scan. The app quickly identifies the succulent species and generates a care plan for that genus, including watering frequency, light conditions, and soil type. You can also upload a photo from your gallery.',
},
{
question: 'How often should I water my succulent?',
@@ -1918,7 +1925,7 @@ const englishSeoPages2: Record<string, SeoPageProfile> = {
{
href: '/plant-identifier-app',
label: 'Plant Identifier App',
description: 'Identify any plant — succulents, houseplants, and garden plants.',
description: 'Identify supported succulents, houseplants, and garden plants from a clear photo.',
},
{
href: '/houseplant-identifier',
@@ -1944,9 +1951,9 @@ const highVolumeSeoPages: Record<string, SeoPageProfile> = {
h1: 'Best Plant Identification App',
tagline: 'Free to identify. Keeps going after the name — care plan, health check, reminders.',
directAnswer:
'GreenLens is a free plant identification app for iOS and Android. Point your camera at any plant, get the species name instantly, and receive a complete care plan — no search redirect, no paywall for basic identification.',
'GreenLens is a free plant identification app for iOS and Android. Point your camera at a plant, review the suggested match, and receive a care plan without being redirected to search results.',
definitionBlock:
'The best plant identification app does more than return a name. It tells you what to do next. GreenLens identifies 450+ plant species for free and automatically generates a care plan, watering reminders, and health diagnostic after every scan — making it the most actionable free plant ID app available.',
'A useful plant identification app does more than return a name. GreenLens combines a catalog of more than 450 plant profiles with care plans, watering reminders, and an optional health check after a scan.',
lastUpdated: 'April 2026',
includeAppSchema: true,
featureTable: {
@@ -1998,7 +2005,7 @@ const highVolumeSeoPages: Record<string, SeoPageProfile> = {
{
question: 'How accurate is GreenLens for plant identification?',
answer:
'GreenLens accurately identifies the most common houseplants, garden plants, and succulents. For everyday plant owners, it is fast and reliable. A clear, well-lit photo of the plant\'s characteristic features leaves, bloom, or growth form produces the best results.',
'GreenLens is designed for common houseplants, garden plants, and succulents. Match quality depends on the species and image quality. A clear, well-lit photo of characteristic features such as leaves, blooms, or growth form produces the most useful suggestion.',
},
{
question: 'Is there a truly free plant identification app?',
@@ -2013,7 +2020,7 @@ const highVolumeSeoPages: Record<string, SeoPageProfile> = {
{
question: 'Can I use GreenLens to identify plants from photos in my gallery?',
answer:
'Yes. GreenLens works with photos from your gallery as well as live camera shots. Upload any clear image of a plant to get the species name and care plan instantly.',
'Yes. GreenLens works with photos from your gallery as well as live camera shots. Upload a clear plant image, review the suggested match, and continue with its care guidance.',
},
],
relatedLinks: [
@@ -2030,19 +2037,20 @@ const highVolumeSeoPages: Record<string, SeoPageProfile> = {
{
href: '/identify-plant-photo',
label: 'Identify Plant by Photo',
description: 'Upload any photo and get the species name and care plan instantly.',
description: 'Upload a clear plant photo, review the suggested match, and continue with care guidance.',
},
],
},
'plant-health-app': {
slug: 'plant-health-app',
metaTitle: 'Plant Health App — Diagnose Symptoms & Save Your Plant | GreenLens',
templateIntent: 'diagnosis',
metaTitle: 'Plant Health App: Assess Plant Symptoms | GreenLens',
metaDescription:
'GreenLens is the plant health app that gives you a concrete next step — not a list of possibilities. Diagnose yellow leaves, root rot signs, and plant emergencies in seconds.',
'GreenLens helps assess visible symptoms such as yellow leaves, wilting, or soft stems and suggests cautious next steps for further checking.',
canonical: '/plant-health-app',
h1: 'Plant Health App',
tagline: 'Something looks wrong. Find out what and what to do about it — in under a second.',
tagline: 'Something looks wrong. Quickly find out what it could be and what to do next.',
directAnswer:
'GreenLens is a plant health app for iOS and Android. When your plant shows symptoms — yellow leaves, soft stems, wilting, or spots — the health check scan identifies the most likely cause and gives you one clear next step. No endless list of possibilities.',
definitionBlock:

View File

@@ -37,10 +37,16 @@ export interface SeoTemplateCopy {
lead: string
steps: { title: string; body: string }[]
}
comparison: {
diagnosisMethodology: {
eyebrow: string
title: string
lead: string
steps: { title: string; body: string }[]
}
comparison: {
eyebrow: string
title: string
intentLead: Record<'identification' | 'diagnosis' | 'care' | 'watering', string>
greenlens: string
alternative: string
tipTitle: string
@@ -100,7 +106,7 @@ export const seoTemplateCopy: Record<Lang, SeoTemplateCopy> = {
stat2Title: 'Ganzheitlich',
stat2Label: 'Erkennung & Pflegeplan',
floatTitle: 'Indische Lotosblume',
floatLabel: 'Erkannt in 0,8s',
floatLabel: 'Schnell analysiert',
imageAlt: 'Smartphone scannt eine Lotusblüte',
},
advantage: {
@@ -112,16 +118,16 @@ export const seoTemplateCopy: Record<Lang, SeoTemplateCopy> = {
title: 'Wusstest du schon?',
items: [
{
title: 'Überwässerung ist Todesursache Nr. 1',
body: 'Die meisten Zimmerpflanzen sterben an Wurzelfäule durch zu häufiges Gießen. GreenLens berechnet präzise Trocknungszeiten.',
title: 'Zu häufiges Gießen kann Wurzeln schädigen',
body: 'Staunässe kann Wurzelfäule begünstigen. GreenLens hilft dabei, Gießintervalle an Pflanze und Standort anzupassen.',
},
{
title: 'Lichtintensität fällt rasant ab',
body: 'Schon 1 Meter vom Fenster entfernt sinkt die Lichtintensität um 50 %. Pflegehinweise berücksichtigen den Standort.',
body: 'Mit zunehmendem Abstand zum Fenster steht Pflanzen oft deutlich weniger Licht zur Verfügung. Pflegehinweise berücksichtigen deshalb den Standort.',
},
{
title: 'Pflanzen reinigen die Raumluft',
body: 'Bestimmte Arten können einen Großteil der Schadstoffe aus der Luft filtern. GreenLens hebt luftreinigende Pflanzen hervor.',
title: 'Der Standort beeinflusst das Wohlbefinden',
body: 'Licht, Temperatur und Luftfeuchtigkeit wirken sich auf Pflanzen unterschiedlich aus. GreenLens bündelt passende Standort- und Pflegehinweise.',
},
],
},
@@ -136,7 +142,7 @@ export const seoTemplateCopy: Record<Lang, SeoTemplateCopy> = {
},
{
title: 'Merkmals-Extraktion',
body: 'Das neuronale Netz isoliert über 120 spezifische Merkmale und vergleicht sie mit einer umfangreichen botanischen Datenbank.',
body: 'Das Modell wertet sichtbare Merkmale aus und vergleicht sie mit Einträgen aus einer botanischen Datenbank.',
},
{
title: 'Diagnose',
@@ -148,10 +154,26 @@ export const seoTemplateCopy: Record<Lang, SeoTemplateCopy> = {
},
],
},
diagnosisMethodology: {
eyebrow: '— Der Gesundheitscheck',
title: 'So wird ein sichtbares Pflanzensymptom eingeordnet',
lead: 'Der Gesundheitscheck verbindet die Fotoanalyse mit artbezogenen Hinweisen und macht daraus einen nachvollziehbaren nächsten Schritt.',
steps: [
{ title: 'Symptom fotografieren', body: 'Ein scharfes Foto von Blatt, Stängel oder betroffener Stelle liefert die Grundlage für die Analyse.' },
{ title: 'Muster prüfen', body: 'Das Modell sucht nach sichtbaren Mustern wie Verfärbungen, Flecken, Welke oder möglichen Schädlingsspuren.' },
{ title: 'Kontext einbeziehen', body: 'Pflanzenart und typische Ursachen helfen dabei, ähnliche Symptome besser voneinander abzugrenzen.' },
{ title: 'Nächsten Schritt zeigen', body: 'GreenLens fasst mögliche Ursachen zusammen und schlägt vorsichtige, praktische Maßnahmen zur weiteren Prüfung vor.' },
],
},
comparison: {
eyebrow: '— Im Vergleich',
title: 'GreenLens vs. einfache Apps',
lead: 'Warum ernsthafte Pflanzenfans auf unsere Plattform statt auf Standard-Erkennungstools setzen: verwertbare Daten statt bloßer Namen.',
intentLead: {
identification: 'Vergleiche, was nach dem Artvorschlag passiert: Pflegehinweise und nächste Schritte statt bloß eines Namens.',
diagnosis: 'Vergleiche, wie sichtbare Symptome eingeordnet werden und ob das Ergebnis einen vorsichtigen, nachvollziehbaren nächsten Schritt bietet.',
care: 'Vergleiche individuelle Pflegehinweise mit allgemeinen Kalendern und starren Standardplänen.',
watering: 'Vergleiche pflanzenbezogene Gießerinnerungen mit einfachen Timern, die Standort und Pflanzenart nicht berücksichtigen.',
},
greenlens: 'GreenLens',
alternative: 'Einfache Apps',
tipTitle: 'Botanik-Tipp',
@@ -209,7 +231,7 @@ export const seoTemplateCopy: Record<Lang, SeoTemplateCopy> = {
stat2Title: 'Holistic',
stat2Label: 'Identification & care plans',
floatTitle: 'Sacred lotus',
floatLabel: 'Identified in 0.8s',
floatLabel: 'Analyzed quickly',
imageAlt: 'Phone scanning a lotus flower',
},
advantage: {
@@ -221,16 +243,16 @@ export const seoTemplateCopy: Record<Lang, SeoTemplateCopy> = {
title: 'Did you know?',
items: [
{
title: 'Overwatering is the #1 cause of death',
body: 'Most houseplants die from root rot caused by overwatering. GreenLens calculates precise drying times.',
title: 'Watering too often can damage roots',
body: 'Waterlogged soil can contribute to root rot. GreenLens helps adapt watering intervals to the plant and its location.',
},
{
title: 'Light intensity drops fast',
body: 'Light intensity drops by 50% just 1 meter from the window. Care guidance takes placement into account.',
body: 'Plants often receive substantially less light as the distance from a window increases. Care guidance therefore takes placement into account.',
},
{
title: 'Plants purify indoor air',
body: 'Certain species can filter a large share of airborne toxins. GreenLens highlights air-purifying plants.',
title: 'Placement shapes plant health',
body: 'Light, temperature, and humidity affect species differently. GreenLens brings relevant placement and care guidance together.',
},
],
},
@@ -245,7 +267,7 @@ export const seoTemplateCopy: Record<Lang, SeoTemplateCopy> = {
},
{
title: 'Feature Extraction',
body: 'Our neural network isolates over 120 specific features and matches them against a vast botanical database.',
body: 'The model evaluates visible features and compares them with entries in a botanical database.',
},
{
title: 'Diagnosis',
@@ -257,10 +279,26 @@ export const seoTemplateCopy: Record<Lang, SeoTemplateCopy> = {
},
],
},
diagnosisMethodology: {
eyebrow: '— The Health Check',
title: 'How a visible plant symptom is assessed',
lead: 'The health check combines photo analysis with species-specific context to suggest a clear next step.',
steps: [
{ title: 'Photograph the symptom', body: 'A sharp photo of the affected leaf, stem, or area provides the basis for analysis.' },
{ title: 'Review visible patterns', body: 'The model looks for patterns such as discoloration, spots, wilting, or possible pest traces.' },
{ title: 'Add plant context', body: 'The species and its common issues help distinguish between symptoms that can look similar.' },
{ title: 'Suggest a next step', body: 'GreenLens summarizes possible causes and offers cautious, practical actions for further checking.' },
],
},
comparison: {
eyebrow: '— Perspective',
title: 'GreenLens vs. Basic Apps',
lead: 'Why serious plant enthusiasts trust our platform over standard identification tools: actionable data, not just trivia.',
intentLead: {
identification: 'Compare what happens after the suggested match: practical care guidance and next steps instead of only a name.',
diagnosis: 'Compare how visible symptoms are assessed and whether the result offers a cautious, understandable next step.',
care: 'Compare plant-specific care guidance with generic calendars and fixed schedules.',
watering: 'Compare plant-specific watering reminders with simple timers that ignore species and placement.',
},
greenlens: 'GreenLens',
alternative: 'Basic apps',
tipTitle: 'Botanical Tip',
@@ -318,7 +356,7 @@ export const seoTemplateCopy: Record<Lang, SeoTemplateCopy> = {
stat2Title: 'Holístico',
stat2Label: 'Identificación y planes',
floatTitle: 'Loto sagrado',
floatLabel: 'Identificada en 0,8s',
floatLabel: 'Analizada rápidamente',
imageAlt: 'Teléfono escaneando una flor de loto',
},
advantage: {
@@ -330,16 +368,16 @@ export const seoTemplateCopy: Record<Lang, SeoTemplateCopy> = {
title: '¿Sabías que?',
items: [
{
title: 'El exceso de riego es la causa n.º 1 de muerte',
body: 'La mayoría de las plantas de interior mueren por pudrición de la raíz debido al exceso de riego. GreenLens calcula tiempos de secado precisos.',
title: 'Regar demasiado puede dañar las raíces',
body: 'El encharcamiento puede favorecer la pudrición de las raíces. GreenLens ayuda a adaptar los intervalos de riego a la planta y su ubicación.',
},
{
title: 'La intensidad de la luz disminuye rápidamente',
body: 'La intensidad de la luz disminuye un 50 % a solo 1 metro de la ventana. Los consejos de cuidado tienen en cuenta la ubicación.',
body: 'Las plantas suelen recibir bastante menos luz a medida que aumenta la distancia de una ventana. Por eso los consejos tienen en cuenta la ubicación.',
},
{
title: 'Las plantas purifican el aire interior',
body: 'Ciertas especies pueden filtrar gran parte de las toxinas del aire. GreenLens destaca las plantas purificadoras.',
title: 'La ubicación influye en la salud',
body: 'La luz, la temperatura y la humedad afectan de forma distinta a cada especie. GreenLens reúne consejos adecuados de ubicación y cuidado.',
},
],
},
@@ -354,7 +392,7 @@ export const seoTemplateCopy: Record<Lang, SeoTemplateCopy> = {
},
{
title: 'Extracción de Características',
body: 'Nuestra red neuronal aísla más de 120 características específicas y las compara con una enorme base de datos botánica.',
body: 'El modelo evalúa rasgos visibles y los compara con entradas de una base de datos botánica.',
},
{
title: 'Diagnóstico',
@@ -366,10 +404,26 @@ export const seoTemplateCopy: Record<Lang, SeoTemplateCopy> = {
},
],
},
diagnosisMethodology: {
eyebrow: '— El chequeo de salud',
title: 'Cómo se evalúa un síntoma visible',
lead: 'El chequeo combina el análisis de la foto con información de la especie para proponer un siguiente paso claro.',
steps: [
{ title: 'Fotografiar el síntoma', body: 'Una foto nítida de la hoja, el tallo o la zona afectada proporciona la base del análisis.' },
{ title: 'Revisar patrones visibles', body: 'El modelo busca patrones como decoloración, manchas, marchitez o posibles rastros de plagas.' },
{ title: 'Añadir contexto', body: 'La especie y sus problemas habituales ayudan a distinguir síntomas que pueden parecer similares.' },
{ title: 'Proponer el siguiente paso', body: 'GreenLens resume posibles causas y ofrece medidas prudentes y prácticas para seguir comprobando.' },
],
},
comparison: {
eyebrow: '— Perspectiva',
title: 'GreenLens vs. Apps Básicas',
lead: 'Por qué los entusiastas serios de las plantas confían en nuestra plataforma más que en herramientas estándar: datos procesables, no solo curiosidades.',
intentLead: {
identification: 'Compara lo que ocurre después de la coincidencia sugerida: cuidados y pasos prácticos en lugar de recibir solo un nombre.',
diagnosis: 'Compara cómo se evalúan los síntomas visibles y si el resultado ofrece un siguiente paso prudente y comprensible.',
care: 'Compara consejos específicos para cada planta con calendarios genéricos y rutinas fijas.',
watering: 'Compara recordatorios de riego por planta con temporizadores simples que no consideran la especie ni la ubicación.',
},
greenlens: 'GreenLens',
alternative: 'Apps básicas',
tipTitle: 'Consejo Botánico',

View File

@@ -83,6 +83,7 @@ export const spanishSeoPageProfiles: Record<string, SeoPageProfile> = {
'app-para-cuidar-plantas': {
slug: 'app-para-cuidar-plantas',
templateIntent: 'care',
locale: 'es',
metaTitle: 'App para cuidar plantas | GreenLens',
metaDescription:
@@ -157,6 +158,7 @@ export const spanishSeoPageProfiles: Record<string, SeoPageProfile> = {
'diagnosticar-enfermedades-plantas': {
slug: 'diagnosticar-enfermedades-plantas',
templateIntent: 'diagnosis',
locale: 'es',
metaTitle: 'Diagnosticar enfermedades de plantas | GreenLens',
metaDescription:

View File

@@ -15,6 +15,7 @@ const nextConfig: NextConfig = {
'/zimmerpflanzen-bestimmen',
'/pflanzen-pflege-app',
'/pflanzen-krankheiten-erkennen',
'/giess-erinnerung-app',
].map((slug) => ({
source: `/de${slug}`,
destination: slug,