From 173aad7b5c5deaceea792201a31ae35109ee59d1 Mon Sep 17 00:00:00 2001 From: yonastewabe Date: Tue, 14 Jul 2026 09:06:43 +0300 Subject: [PATCH] feat(seo): Add metadata and SEO improvements to passenger portal --- .github/workflows/deploy.yml | 1 - .../portal/src/app/about/layout.tsx | 21 ++++ .../portal/src/app/contact/layout.tsx | 21 ++++ .../portal/src/app/guide/layout.tsx | 28 ++++++ .../portal/src/app/help/layout.tsx | 23 +++++ .../portal/src/app/layout.tsx | 97 ++++++++++++++++++- .../portal/src/app/packages/[id]/layout.tsx | 80 +++++++++++++++ .../portal/src/app/packages/layout.tsx | 23 +++++ .../edr-passenger-web/portal/src/app/page.tsx | 17 ++++ .../portal/src/app/robots.ts | 37 +++++++ .../portal/src/app/services/layout.tsx | 23 +++++ .../portal/src/app/sitemap.ts | 59 +++++++++++ .../portal/src/components/JsonLd.tsx | 12 +++ .../portal/src/middleware.ts | 23 ++++- 14 files changed, 459 insertions(+), 6 deletions(-) create mode 100644 apps/edr-passenger-web/portal/src/app/about/layout.tsx create mode 100644 apps/edr-passenger-web/portal/src/app/contact/layout.tsx create mode 100644 apps/edr-passenger-web/portal/src/app/guide/layout.tsx create mode 100644 apps/edr-passenger-web/portal/src/app/help/layout.tsx create mode 100644 apps/edr-passenger-web/portal/src/app/packages/[id]/layout.tsx create mode 100644 apps/edr-passenger-web/portal/src/app/packages/layout.tsx create mode 100644 apps/edr-passenger-web/portal/src/app/robots.ts create mode 100644 apps/edr-passenger-web/portal/src/app/services/layout.tsx create mode 100644 apps/edr-passenger-web/portal/src/app/sitemap.ts create mode 100644 apps/edr-passenger-web/portal/src/components/JsonLd.tsx diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 057cb0c1b..f0beccd20 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -2,7 +2,6 @@ name: Deploy Stacks on: push: branches: - - main - dev - staging workflow_dispatch: diff --git a/apps/edr-passenger-web/portal/src/app/about/layout.tsx b/apps/edr-passenger-web/portal/src/app/about/layout.tsx new file mode 100644 index 000000000..a7bb1b25d --- /dev/null +++ b/apps/edr-passenger-web/portal/src/app/about/layout.tsx @@ -0,0 +1,21 @@ +import type { Metadata } from 'next'; + +export const metadata: Metadata = { + title: 'About EDR – Connecting East Africa by Rail', + description: + 'Learn about the Ethio-Djibouti Railway (EDR): our mission to connect Ethiopia and Djibouti with comfortable, affordable, and sustainable train travel.', + alternates: { + canonical: '/about', + }, + openGraph: { + title: 'About EDR – Connecting East Africa by Rail', + description: + 'Our mission is to provide reliable, affordable, and comfortable train travel connecting Ethiopia and Djibouti.', + url: '/about', + images: [{ url: '/edr-banner.jpg', width: 1200, height: 630, alt: 'EDR Railway – About Us' }], + }, +}; + +export default function AboutLayout({ children }: { children: React.ReactNode }) { + return children; +} diff --git a/apps/edr-passenger-web/portal/src/app/contact/layout.tsx b/apps/edr-passenger-web/portal/src/app/contact/layout.tsx new file mode 100644 index 000000000..3a5c61836 --- /dev/null +++ b/apps/edr-passenger-web/portal/src/app/contact/layout.tsx @@ -0,0 +1,21 @@ +import type { Metadata } from 'next'; + +export const metadata: Metadata = { + title: 'Contact EDR – Get in Touch', + description: + 'Contact the Ethio-Djibouti Railway (EDR) support team. We are available to assist with your train journey.', + alternates: { + canonical: '/contact', + }, + openGraph: { + title: 'Contact EDR – Get in Touch', + description: + 'Reach the EDR support team by phone, email, or in person. We are available to assist with your train journey.', + url: '/contact', + images: [{ url: '/edr-banner.jpg', width: 1200, height: 630, alt: 'EDR Railway – Contact Us' }], + }, +}; + +export default function ContactLayout({ children }: { children: React.ReactNode }) { + return children; +} diff --git a/apps/edr-passenger-web/portal/src/app/guide/layout.tsx b/apps/edr-passenger-web/portal/src/app/guide/layout.tsx new file mode 100644 index 000000000..417c46cf3 --- /dev/null +++ b/apps/edr-passenger-web/portal/src/app/guide/layout.tsx @@ -0,0 +1,28 @@ +import type { Metadata } from 'next'; + +export const metadata: Metadata = { + title: 'How to Book a Train Ticket – EDR Step-by-Step Guide', + description: + 'Step-by-step guide to booking an EDR train ticket online: search trains, select your seat class, enter passenger details, and complete payment.', + alternates: { + canonical: '/guide', + }, + openGraph: { + title: 'How to Book a Train Ticket – EDR Step-by-Step Guide', + description: + 'Follow our simple guide to book your EDR train journey in minutes.', + url: '/guide', + images: [ + { + url: '/edr-banner.jpg', + width: 1200, + height: 630, + alt: 'EDR Railway – How to Book a Train Ticket', + }, + ], + }, +}; + +export default function GuideLayout({ children }: { children: React.ReactNode }) { + return children; +} diff --git a/apps/edr-passenger-web/portal/src/app/help/layout.tsx b/apps/edr-passenger-web/portal/src/app/help/layout.tsx new file mode 100644 index 000000000..0211d6d23 --- /dev/null +++ b/apps/edr-passenger-web/portal/src/app/help/layout.tsx @@ -0,0 +1,23 @@ +import type { Metadata } from 'next'; + +export const metadata: Metadata = { + title: 'Help & FAQs – EDR Train Booking', + description: + 'Find answers to common questions about booking EDR train tickets: how to book, passenger pricing, identity verification, seat classes, payment methods, and more.', + alternates: { + canonical: '/help', + }, + openGraph: { + title: 'Help & FAQs – EDR Train Booking', + description: + 'Answers to your questions about booking EDR train tickets, payment methods, identity verification, and seat selection.', + url: '/help', + images: [ + { url: '/edr-banner.jpg', width: 1200, height: 630, alt: 'EDR Railway – Help & FAQs' }, + ], + }, +}; + +export default function HelpLayout({ children }: { children: React.ReactNode }) { + return children; +} diff --git a/apps/edr-passenger-web/portal/src/app/layout.tsx b/apps/edr-passenger-web/portal/src/app/layout.tsx index 7e6049956..7337c18d6 100644 --- a/apps/edr-passenger-web/portal/src/app/layout.tsx +++ b/apps/edr-passenger-web/portal/src/app/layout.tsx @@ -7,10 +7,61 @@ import MobileTopBar from '@/components/MobileTopBar'; import BottomTabBar from '@/components/BottomTabBar'; import { LoadingIndicator } from '@/components/LoadingIndicator'; import SupportWidget from '@/features/support/SupportWidgetLazy'; +import { JsonLd } from '@/components/JsonLd'; + +const siteUrl = process.env.NEXT_PUBLIC_SITE_URL ?? 'https://passenger.edrsc.com'; export const metadata: Metadata = { - title: 'EDR Passenger Portal - Book your train journey', - description: 'Book train tickets on the Ethio-Djibouti Railway', + metadataBase: new URL(siteUrl), + title: { + default: 'EDR Passenger Portal – Book Train Tickets Online', + template: '%s | EDR Passenger Portal', + }, + description: + 'Book train tickets on the Ethio-Djibouti Railway. Travel between Ethiopia and Djibouti with easy online booking, seat selection, and multiple payment options.', + authors: [{ name: 'EDR – Ethio-Djibouti Railway' }], + creator: 'EDR – Ethio-Djibouti Railway', + publisher: 'EDR – Ethio-Djibouti Railway', + robots: { + index: true, + follow: true, + googleBot: { + index: true, + follow: true, + 'max-snippet': -1, + 'max-image-preview': 'large', + 'max-video-preview': -1, + }, + }, + openGraph: { + type: 'website', + locale: 'en_US', + url: siteUrl, + siteName: 'EDR Passenger Portal', + title: 'EDR Passenger Portal – Book Train Tickets Online', + description: + 'Book train tickets on the Ethio-Djibouti Railway. Comfortable seats, flexible payment options, and easy online booking.', + images: [ + { + url: '/edr-banner.jpg', + width: 1200, + height: 630, + alt: 'EDR Ethio-Djibouti Railway – Book your train journey', + }, + ], + }, + twitter: { + card: 'summary_large_image', + title: 'EDR Passenger Portal – Book Train Tickets Online', + description: + 'Book train tickets on the Ethio-Djibouti Railway. Comfortable seats, flexible payment options, and easy online booking.', + images: ['/edr-banner.jpg'], + }, + icons: { + icon: '/edr-logo.png', + shortcut: '/edr-logo.png', + apple: '/edr-logo.png', + }, }; // viewportFit: 'cover' lets fixed bottom bars (e.g. the payment page's Pay @@ -29,8 +80,48 @@ export default function RootLayout({ }) { // Nonce set per-request by middleware; required for this inline script under the CSP. const nonce = headers().get('x-nonce') ?? undefined; + + const organizationSchema = { + '@context': 'https://schema.org', + '@type': 'Organization', + name: 'Ethio-Djibouti Railway (EDR)', + url: siteUrl, + logo: `${siteUrl}/edr-logo.png`, + contactPoint: { + '@type': 'ContactPoint', + telephone: '9546', + contactType: 'customer service', + availableLanguage: ['English', 'Amharic'], + }, + address: { + '@type': 'PostalAddress', + addressLocality: 'Addis Ababa', + addressCountry: 'ET', + }, + sameAs: [], + }; + + const websiteSchema = { + '@context': 'https://schema.org', + '@type': 'WebSite', + name: 'EDR Passenger Portal', + url: siteUrl, + potentialAction: { + '@type': 'SearchAction', + target: { + '@type': 'EntryPoint', + urlTemplate: `${siteUrl}/booking/search?q={search_term_string}`, + }, + 'query-input': 'required name=search_term_string', + }, + }; + return ( - + + + + +