Files
doormile_react/src/app/blog/[slug]/page.tsx
2026-06-12 14:55:29 +05:30

117 lines
3.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React from "react";
import type { Metadata } from "next";
import { notFound } from "next/navigation";
import SingleBlog from "@/components/sections/SingleBlog";
import BlogPostFooter from "@/components/sections/BlogPostFooter";
import { getPostBySlug, getAllSlugs, SITE_URL } from "@/data/blog";
type Params = { slug: string };
// Required for `output: "export"`: prerender every post at build time.
export function generateStaticParams(): Params[] {
return getAllSlugs().map((slug) => ({ slug }));
}
export async function generateMetadata({
params,
}: {
params: Promise<Params>;
}): Promise<Metadata> {
const { slug } = await params;
const post = getPostBySlug(slug);
if (!post) {
return { title: "Article Not Found Doormile" };
}
const url = `${SITE_URL}/blog/${post.slug}`;
const image = `${SITE_URL}${post.image}`;
return {
title: `${post.title} Doormile`,
description: post.excerpt,
keywords: [post.category, "last-mile logistics", "EV fleet", "MileTruth", "route optimisation"],
authors: [{ name: post.author }],
alternates: { canonical: url },
openGraph: {
type: "article",
title: post.title,
description: post.excerpt,
url,
siteName: "Doormile",
images: [{ url: image, alt: post.title }],
publishedTime: new Date(`${post.date}T00:00:00Z`).toISOString(),
authors: [post.author],
},
twitter: {
card: "summary_large_image",
title: post.title,
description: post.excerpt,
images: [image],
},
};
}
export default async function BlogPostPage({
params,
}: {
params: Promise<Params>;
}) {
const { slug } = await params;
const post = getPostBySlug(slug);
if (!post) notFound();
const url = `${SITE_URL}/blog/${post.slug}`;
const articleSchema = {
"@context": "https://schema.org",
"@type": "Article",
headline: post.title,
description: post.excerpt,
image: [`${SITE_URL}${post.image}`],
datePublished: new Date(`${post.date}T00:00:00Z`).toISOString(),
dateModified: new Date(`${post.date}T00:00:00Z`).toISOString(),
author: { "@type": "Organization", name: post.author, url: SITE_URL },
publisher: {
"@type": "Organization",
name: "Doormile",
logo: {
"@type": "ImageObject",
url: `${SITE_URL}/images/cropped-image-2.png`,
},
},
mainEntityOfPage: { "@type": "WebPage", "@id": url },
articleSection: post.category,
};
const breadcrumbSchema = {
"@context": "https://schema.org",
"@type": "BreadcrumbList",
itemListElement: [
{ "@type": "ListItem", position: 1, name: "Home", item: SITE_URL },
{ "@type": "ListItem", position: 2, name: "Blog", item: `${SITE_URL}/blog` },
{ "@type": "ListItem", position: 3, name: post.title, item: url },
],
};
return (
<div className="content-wrapper content-wrapper-may-contain-elementor-code content-wrapper-sidebar-position-none">
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(articleSchema) }}
/>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(breadcrumbSchema) }}
/>
<div className="content">
<div className="content-inner">
<SingleBlog post={post} />
<BlogPostFooter slug={post.slug} />
</div>
</div>
</div>
);
}