diff --git a/.codex-tmp/greenlens-tiktok-2026-07-10-1080p/slide-1.jpg b/.codex-tmp/greenlens-tiktok-2026-07-10-1080p/slide-1.jpg new file mode 100644 index 0000000..f00a848 Binary files /dev/null and b/.codex-tmp/greenlens-tiktok-2026-07-10-1080p/slide-1.jpg differ diff --git a/.codex-tmp/greenlens-tiktok-2026-07-10-1080p/slide-2.jpg b/.codex-tmp/greenlens-tiktok-2026-07-10-1080p/slide-2.jpg new file mode 100644 index 0000000..cea2bbf Binary files /dev/null and b/.codex-tmp/greenlens-tiktok-2026-07-10-1080p/slide-2.jpg differ diff --git a/.codex-tmp/greenlens-tiktok-2026-07-10-1080p/slide-3.jpg b/.codex-tmp/greenlens-tiktok-2026-07-10-1080p/slide-3.jpg new file mode 100644 index 0000000..5fce033 Binary files /dev/null and b/.codex-tmp/greenlens-tiktok-2026-07-10-1080p/slide-3.jpg differ diff --git a/.codex-tmp/greenlens-tiktok-2026-07-10-1080p/slide-4.jpg b/.codex-tmp/greenlens-tiktok-2026-07-10-1080p/slide-4.jpg new file mode 100644 index 0000000..f0bd7f1 Binary files /dev/null and b/.codex-tmp/greenlens-tiktok-2026-07-10-1080p/slide-4.jpg differ diff --git a/.codex-tmp/greenlens-tiktok-2026-07-10-1080p/slide-5.jpg b/.codex-tmp/greenlens-tiktok-2026-07-10-1080p/slide-5.jpg new file mode 100644 index 0000000..df92058 Binary files /dev/null and b/.codex-tmp/greenlens-tiktok-2026-07-10-1080p/slide-5.jpg differ diff --git a/.codex-tmp/greenlens-tiktok-2026-07-10-1080p/slide-6.jpg b/.codex-tmp/greenlens-tiktok-2026-07-10-1080p/slide-6.jpg new file mode 100644 index 0000000..19b4f97 Binary files /dev/null and b/.codex-tmp/greenlens-tiktok-2026-07-10-1080p/slide-6.jpg differ diff --git a/.codex-tmp/greenlens-tiktok-2026-07-10/slide-1.jpg b/.codex-tmp/greenlens-tiktok-2026-07-10/slide-1.jpg new file mode 100644 index 0000000..ed85078 Binary files /dev/null and b/.codex-tmp/greenlens-tiktok-2026-07-10/slide-1.jpg differ diff --git a/.codex-tmp/greenlens-tiktok-2026-07-10/slide-2.jpg b/.codex-tmp/greenlens-tiktok-2026-07-10/slide-2.jpg new file mode 100644 index 0000000..8437c4c Binary files /dev/null and b/.codex-tmp/greenlens-tiktok-2026-07-10/slide-2.jpg differ diff --git a/.codex-tmp/greenlens-tiktok-2026-07-10/slide-3.jpg b/.codex-tmp/greenlens-tiktok-2026-07-10/slide-3.jpg new file mode 100644 index 0000000..497c10b Binary files /dev/null and b/.codex-tmp/greenlens-tiktok-2026-07-10/slide-3.jpg differ diff --git a/.codex-tmp/greenlens-tiktok-2026-07-10/slide-4.jpg b/.codex-tmp/greenlens-tiktok-2026-07-10/slide-4.jpg new file mode 100644 index 0000000..510bd8f Binary files /dev/null and b/.codex-tmp/greenlens-tiktok-2026-07-10/slide-4.jpg differ diff --git a/.codex-tmp/greenlens-tiktok-2026-07-10/slide-5.jpg b/.codex-tmp/greenlens-tiktok-2026-07-10/slide-5.jpg new file mode 100644 index 0000000..cfb6a63 Binary files /dev/null and b/.codex-tmp/greenlens-tiktok-2026-07-10/slide-5.jpg differ diff --git a/.codex-tmp/greenlens-tiktok-2026-07-10/slide-6.jpg b/.codex-tmp/greenlens-tiktok-2026-07-10/slide-6.jpg new file mode 100644 index 0000000..3c4d603 Binary files /dev/null and b/.codex-tmp/greenlens-tiktok-2026-07-10/slide-6.jpg differ diff --git a/greenlns-landing/app/en/page.tsx b/greenlns-landing/app/en/page.tsx index 01c22aa..0985e6e 100644 --- a/greenlns-landing/app/en/page.tsx +++ b/greenlns-landing/app/en/page.tsx @@ -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 + return } diff --git a/greenlns-landing/app/es/page.tsx b/greenlns-landing/app/es/page.tsx index d1b9d05..61480df 100644 --- a/greenlns-landing/app/es/page.tsx +++ b/greenlns-landing/app/es/page.tsx @@ -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 + return } diff --git a/greenlns-landing/app/layout.tsx b/greenlns-landing/app/layout.tsx index b8c8379..4c5bb98 100644 --- a/greenlns-landing/app/layout.tsx +++ b/greenlns-landing/app/layout.tsx @@ -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 ( @@ -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 /> - {children} + {children} ) diff --git a/greenlns-landing/app/page.tsx b/greenlns-landing/app/page.tsx index 9dcf86d..d71be7f 100644 --- a/greenlns-landing/app/page.tsx +++ b/greenlns-landing/app/page.tsx @@ -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 ( <>