Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/app/(main)/berita/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,16 @@ export async function generateMetadata({
title: "Berita tidak ditemukan",
};

const baseUrl = process.env.URL || "https://www.moklet.org";

return {
title: post.title,
description: post.description.trim() || null,
authors: { name: post.user.name },
openGraph: {
url: `${process.env.URL ?? "https://www.moklet.org"}/berita/${post.slug}`,
url: `${baseUrl}/berita/${post.slug}`,
title: post.title,
images: [{ url: `${baseUrl}/api/post/${post.slug}/og-image.png` }],
description: post.description.trim() || undefined,
type: "article",
publishedTime: new Date(post.published_at!).toISOString(),
Expand All @@ -49,6 +52,7 @@ export async function generateMetadata({
export default async function Post({
params,
}: Readonly<{ params: { slug: string } }>) {
const baseUrl = process.env.URL || "https://www.moklet.org";
const post = await findPost({ slug: params.slug, published: true });

if (!post) notFound();
Expand All @@ -57,10 +61,12 @@ export default async function Post({
const jsonLd: WithContext<NewsArticle> = {
"@context": "https://schema.org",
"@type": "NewsArticle",
image: `${baseUrl}/api/post/${post.slug}/og-image.png`,
description: post.description,
headline: post.title,
datePublished: new Date(post.published_at!).toISOString(),
dateModified: new Date(post.updated_at).toISOString(),
thumbnailUrl: `${baseUrl}/api/post/${post.slug}/og-image.png`,
};

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { FaPencilAlt } from "react-icons/fa";
import { CSSProperties } from "react";
import { findPost } from "@/utils/database/post.query";
import { stripMarkdown, trimName } from "@/utils/atomics";
import { notFound } from "next/navigation";

const montserratMedium = readFileSync(
path.join(process.cwd(), "public/fonts/Montserrat-Medium.ttf"),
Expand All @@ -19,100 +20,99 @@ const styles: Record<string, CSSProperties> = {
container: {
display: "flex",
flexDirection: "column" as const,
width: "600px",
height: "600px",
width: "1200px",
height: "1200px",
backgroundColor: "#ffffff",
fontFamily: "Montserrat, sans-serif",
position: "relative",
},
headerImage: {
width: "100%",
height: "250px",
height: "500px",
objectFit: "cover" as const,
},
contentContainer: {
backgroundColor: "#ffffff",
padding: "15px 20px",
padding: "30px 40px",
display: "flex",
flexDirection: "column" as const,
flex: 1,
},
tagsContainer: {
display: "flex",
gap: "8px",
marginTop: "2px",
gap: "15px",
marginTop: "5px",
flexWrap: "wrap" as const,
justifyItems: "center",
},
tag: {
backgroundColor: "#FFF0F0",
color: "#E04E4E",
borderRadius: "15px",
fontSize: 12,
padding: "5px 10px",
borderRadius: "20px",
fontSize: 20,
padding: "10px 20px",
},
articleContainer: {
display: "flex",
flexDirection: "column" as const,
textAlign: "left" as const,
marginTop: 10,
marginTop: 20,
},
title: {
fontSize: 24,
fontSize: 52,
color: "#000000",
marginBottom: 5,
marginBottom: 10,
fontWeight: 700,
textAlign: "left" as const,
lineHeight: 1.2,
},
content: {
fontSize: 14,
fontSize: 24,
color: "#333333",
marginTop: 5,
marginBottom: 8,
lineHeight: 1.4,
marginTop: 10,
marginBottom: 15,
lineHeight: 1.5,
fontWeight: 500,
},
author: {
fontSize: 12,
marginTop: "8px",
fontSize: 22,
marginTop: "15px",
color: "#333333",
fontWeight: 500,
display: "flex",
alignItems: "center",
},
authorName: {
fontWeight: 700,
marginLeft: "3px",
marginLeft: "4px",
},
pencilIcon: {
marginRight: "4px",
marginRight: "8px",
},
footer: {
display: "flex",
alignItems: "center",
justifyContent: "space-between",
backgroundColor: "#E04E4E",
color: "#FFF",
padding: "8px 15px",
padding: "15px 30px",
position: "absolute",
bottom: 0,
width: "100%",
boxSizing: "border-box" as const,
},
footerLogo: {
height: 25,
height: 45,
},
footerText: {
fontSize: 12,
fontSize: 24,
fontWeight: 500,
maxWidth: "400px",
},
};

export const options: ImageResponseOptions = {
width: 600,
height: 600,
width: 1200,
height: 1200,
fonts: [
{
name: "Montserrat",
Expand All @@ -129,29 +129,19 @@ export const options: ImageResponseOptions = {
],
};

export function generateImageMetadata() {
return [
{
contentType: "image/png",
size: { width: 600, height: 600 },
id: "medium",
},
];
}

export default async function opengraphImage({
params,
}: {
params: { slug: string };
}) {
const post = await findPost({ slug: params.slug, published: true });
export async function GET(
request: Request,
{ params }: { params: Promise<{ slug: string }> },
) {
const { slug } = await params;
const post = await findPost({ slug: slug, published: true });

if (!post) return <h1>Not Found</h1>;
if (!post) return notFound();

const baseUrl = process.env.URL || "https://www.moklet.org";

const contentPreview =
stripMarkdown(post.content.split(" ").slice(0, 30).join(" ")) + "...";
stripMarkdown(post.content.split(" ").slice(0, 50).join(" ")) + "...";

return new ImageResponse(
(
Expand All @@ -160,7 +150,7 @@ export default async function opengraphImage({

<div style={styles.contentContainer}>
<div style={styles.tagsContainer}>
{post.tags.slice(0, 2).map((tag) => (
{post.tags.slice(0, 3).map((tag) => (
<div key={`tag-${tag.tagName}`} style={styles.tag}>
{tag.tagName}
</div>
Expand All @@ -173,7 +163,7 @@ export default async function opengraphImage({
<p style={styles.content}>{contentPreview}</p>

<p style={styles.author}>
<FaPencilAlt style={styles.pencilIcon} size={10} /> Ditulis oleh
<FaPencilAlt style={styles.pencilIcon} size={18} /> Ditulis oleh
<span style={styles.authorName}>{trimName(post.user.name)}</span>
</p>
</div>
Expand Down