Skip to content

Commit 873f476

Browse files
authored
Merge pull request #163 from code0-tech/feat/seo-and-og
Feat/seo and og
2 parents 43ce80d + 6710a70 commit 873f476

26 files changed

Lines changed: 7343 additions & 56 deletions

File tree

export/blog.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

export/media.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
[{"id":141,"alt":"Github action SDK CodeZero","href":null,"updatedAt":"2026-03-25T12:01:38.170Z","createdAt":"2026-03-25T12:01:38.169Z","url":"/api/media/file/Github_Action_SDK_CodeZero.png","thumbnailURL":null,"filename":"Github_Action_SDK_CodeZero.png","mimeType":"image/png","filesize":524187,"width":2940,"height":1666,"focalX":50,"focalY":50},{"id":142,"alt":"Flow builder suggestion menu CodeZero","href":null,"updatedAt":"2026-03-25T11:55:33.672Z","createdAt":"2026-03-25T11:55:33.672Z","url":"/api/media/file/Flow_Builder_Suggestion_Menu_Feature.png","thumbnailURL":null,"filename":"Flow_Builder_Suggestion_Menu_Feature.png","mimeType":"image/png","filesize":490427,"width":2940,"height":1664,"focalX":50,"focalY":50},{"id":143,"alt":"Runtime overview page CodeZero","href":null,"updatedAt":"2026-03-25T11:53:05.308Z","createdAt":"2026-03-25T11:53:05.307Z","url":"/api/media/file/Runtime_Overview_Page.png","thumbnailURL":null,"filename":"Runtime_Overview_Page.png","mimeType":"image/png","filesize":333824,"width":2940,"height":1668,"focalX":50,"focalY":50},{"id":144,"alt":"Flow builder nodes feature CodeZero","href":null,"updatedAt":"2026-03-25T11:38:02.809Z","createdAt":"2026-03-25T11:38:02.809Z","url":"/api/media/file/Flow_Builder_Nodes_Feature.png","thumbnailURL":null,"filename":"Flow_Builder_Nodes_Feature.png","mimeType":"image/png","filesize":407177,"width":2940,"height":1666,"focalX":50,"focalY":50},{"id":145,"alt":"Organization overview page CodeZero","href":null,"updatedAt":"2026-03-25T11:30:37.189Z","createdAt":"2026-03-25T11:30:37.189Z","url":"/api/media/file/Organization_Overview_Page.png","thumbnailURL":null,"filename":"Organization_Overview_Page.png","mimeType":"image/png","filesize":340618,"width":2940,"height":1666,"focalX":50,"focalY":50},{"id":146,"alt":"Organization create page CodeZero","href":null,"updatedAt":"2026-03-25T11:30:37.164Z","createdAt":"2026-03-25T11:30:37.164Z","url":"/api/media/file/Organization_Create_Page.png","thumbnailURL":null,"filename":"Organization_Create_Page.png","mimeType":"image/png","filesize":348465,"width":2940,"height":1664,"focalX":50,"focalY":50},{"id":147,"alt":"Role overview page CodeZero","href":null,"updatedAt":"2026-03-25T11:21:38.738Z","createdAt":"2026-03-25T11:21:38.738Z","url":"/api/media/file/Role_Overview_Page.png","thumbnailURL":null,"filename":"Role_Overview_Page.png","mimeType":"image/png","filesize":396501,"width":2940,"height":1666,"focalX":50,"focalY":50},{"id":148,"alt":"Role add page CodeZero","href":null,"updatedAt":"2026-03-25T11:21:38.691Z","createdAt":"2026-03-25T11:21:38.691Z","url":"/api/media/file/Role_Add_Page.png","thumbnailURL":null,"filename":"Role_Add_Page.png","mimeType":"image/png","filesize":338014,"width":2940,"height":1666,"focalX":50,"focalY":50},{"id":149,"alt":"Role permission page CodeZero","href":null,"updatedAt":"2026-03-25T11:21:38.647Z","createdAt":"2026-03-25T11:21:38.647Z","url":"/api/media/file/Role_Permission_Page.png","thumbnailURL":null,"filename":"Role_Permission_Page.png","mimeType":"image/png","filesize":613737,"width":2940,"height":1666,"focalX":50,"focalY":50},{"id":150,"alt":"Member overview page CodeZero","href":null,"updatedAt":"2026-03-25T11:13:20.805Z","createdAt":"2026-03-25T11:13:20.805Z","url":"/api/media/file/Member_Overview_Page.png","thumbnailURL":null,"filename":"Member_Overview_Page.png","mimeType":"image/png","filesize":390811,"width":2940,"height":1668,"focalX":50,"focalY":50},{"id":151,"alt":"Member remove feature CodeZero","href":null,"updatedAt":"2026-03-25T11:13:20.787Z","createdAt":"2026-03-25T11:13:20.787Z","url":"/api/media/file/Member_Remove_Feature.png","thumbnailURL":null,"filename":"Member_Remove_Feature.png","mimeType":"image/png","filesize":354065,"width":2940,"height":1664,"focalX":50,"focalY":50},{"id":152,"alt":"Member assign roles feature CodeZero","href":null,"updatedAt":"2026-03-25T11:13:20.769Z","createdAt":"2026-03-25T11:13:20.769Z","url":"/api/media/file/Member_Assign_Roles_Feature.png","thumbnailURL":null,"filename":"Member_Assign_Roles_Feature.png","mimeType":"image/png","filesize":379400,"width":2940,"height":1664,"focalX":50,"focalY":50},{"id":153,"alt":"Member add feature CodeZero","href":null,"updatedAt":"2026-03-25T11:13:20.742Z","createdAt":"2026-03-25T11:13:20.742Z","url":"/api/media/file/Member_Add_Feature.png","thumbnailURL":null,"filename":"Member_Add_Feature.png","mimeType":"image/png","filesize":350024,"width":2940,"height":1666,"focalX":50,"focalY":50},{"id":154,"alt":"Project overview page CodeZero","href":null,"updatedAt":"2026-03-25T11:05:42.234Z","createdAt":"2026-03-25T11:05:42.234Z","url":"/api/media/file/Project_Overview_Feature.png","thumbnailURL":null,"filename":"Project_Overview_Feature.png","mimeType":"image/png","filesize":330250,"width":2940,"height":1666,"focalX":50,"focalY":50},{"id":155,"alt":"Create project in CodeZero","href":null,"updatedAt":"2026-03-25T11:05:01.102Z","createdAt":"2026-03-25T11:05:01.102Z","url":"/api/media/file/Create_Project_Feature.png","thumbnailURL":null,"filename":"Create_Project_Feature.png","mimeType":"image/png","filesize":378671,"width":2940,"height":1666,"focalX":50,"focalY":50},{"id":156,"alt":"Logistic automation workflow GLS CodeZero","href":null,"updatedAt":"2026-03-25T10:05:48.175Z","createdAt":"2026-03-25T10:05:48.175Z","url":"/api/media/file/Logistic_Use-Case-1.png","thumbnailURL":null,"filename":"Logistic_Use-Case-1.png","mimeType":"image/png","filesize":113308,"width":1920,"height":1080,"focalX":50,"focalY":50},{"id":157,"alt":"Discord bot automation CodeZero","href":null,"updatedAt":"2026-03-25T10:05:48.152Z","createdAt":"2026-03-25T10:05:48.152Z","url":"/api/media/file/Chatbot_Use-Case-1.png","thumbnailURL":null,"filename":"Chatbot_Use-Case-1.png","mimeType":"image/png","filesize":74140,"width":1920,"height":1080,"focalX":50,"focalY":50},{"id":158,"alt":"AI Use Case ChatGPT MCP Claude CodeZero","href":null,"updatedAt":"2026-03-25T10:05:48.123Z","createdAt":"2026-03-25T10:05:48.123Z","url":"/api/media/file/AI_Use-Case-1.png","thumbnailURL":null,"filename":"AI_Use-Case-1.png","mimeType":"image/png","filesize":126673,"width":1920,"height":1080,"focalX":50,"focalY":50},{"id":159,"alt":"Blog sample Image","href":null,"updatedAt":"2026-03-07T05:59:34.732Z","createdAt":"2026-03-07T05:59:34.731Z","url":"/api/media/file/blog-sample-image.jpg","thumbnailURL":null,"filename":"blog-sample-image.jpg","mimeType":"image/jpeg","filesize":75240,"width":864,"height":576,"focalX":50,"focalY":50},{"id":160,"alt":"Marius Ahsmus Bild","href":null,"updatedAt":"2026-03-07T05:28:39.443Z","createdAt":"2026-03-07T05:15:45.957Z","url":"/api/media/file/NDOLqYAv_400x400.jpg","thumbnailURL":null,"filename":"NDOLqYAv_400x400.jpg","mimeType":"image/jpeg","filesize":28513,"width":400,"height":400,"focalX":50,"focalY":50},{"id":161,"alt":"GLS Logo","href":"https://gls-group.com/","updatedAt":"2026-02-25T11:12:48.228Z","createdAt":"2026-02-25T11:08:24.824Z","url":"/api/media/file/gls_logo.png","thumbnailURL":null,"filename":"gls_logo.png","mimeType":"image/png","filesize":19352,"width":960,"height":337,"focalX":50,"focalY":50}]
1+
[{"id":162,"alt":"Code0 OG Image","href":null,"updatedAt":"2026-03-26T18:45:03.880Z","createdAt":"2026-03-26T18:45:03.880Z","url":"/api/media/file/og-image.png","thumbnailURL":null,"filename":"og-image.png","mimeType":"image/png","filesize":1003908,"width":1920,"height":1080,"focalX":50,"focalY":50},{"id":141,"alt":"Github action SDK CodeZero","href":null,"updatedAt":"2026-03-25T12:01:38.170Z","createdAt":"2026-03-25T12:01:38.169Z","url":"/api/media/file/Github_Action_SDK_CodeZero.png","thumbnailURL":null,"filename":"Github_Action_SDK_CodeZero.png","mimeType":"image/png","filesize":524187,"width":2940,"height":1666,"focalX":50,"focalY":50},{"id":142,"alt":"Flow builder suggestion menu CodeZero","href":null,"updatedAt":"2026-03-25T11:55:33.672Z","createdAt":"2026-03-25T11:55:33.672Z","url":"/api/media/file/Flow_Builder_Suggestion_Menu_Feature.png","thumbnailURL":null,"filename":"Flow_Builder_Suggestion_Menu_Feature.png","mimeType":"image/png","filesize":490427,"width":2940,"height":1664,"focalX":50,"focalY":50},{"id":143,"alt":"Runtime overview page CodeZero","href":null,"updatedAt":"2026-03-25T11:53:05.308Z","createdAt":"2026-03-25T11:53:05.307Z","url":"/api/media/file/Runtime_Overview_Page.png","thumbnailURL":null,"filename":"Runtime_Overview_Page.png","mimeType":"image/png","filesize":333824,"width":2940,"height":1668,"focalX":50,"focalY":50},{"id":144,"alt":"Flow builder nodes feature CodeZero","href":null,"updatedAt":"2026-03-25T11:38:02.809Z","createdAt":"2026-03-25T11:38:02.809Z","url":"/api/media/file/Flow_Builder_Nodes_Feature.png","thumbnailURL":null,"filename":"Flow_Builder_Nodes_Feature.png","mimeType":"image/png","filesize":407177,"width":2940,"height":1666,"focalX":50,"focalY":50},{"id":145,"alt":"Organization overview page CodeZero","href":null,"updatedAt":"2026-03-25T11:30:37.189Z","createdAt":"2026-03-25T11:30:37.189Z","url":"/api/media/file/Organization_Overview_Page.png","thumbnailURL":null,"filename":"Organization_Overview_Page.png","mimeType":"image/png","filesize":340618,"width":2940,"height":1666,"focalX":50,"focalY":50},{"id":146,"alt":"Organization create page CodeZero","href":null,"updatedAt":"2026-03-25T11:30:37.164Z","createdAt":"2026-03-25T11:30:37.164Z","url":"/api/media/file/Organization_Create_Page.png","thumbnailURL":null,"filename":"Organization_Create_Page.png","mimeType":"image/png","filesize":348465,"width":2940,"height":1664,"focalX":50,"focalY":50},{"id":147,"alt":"Role overview page CodeZero","href":null,"updatedAt":"2026-03-25T11:21:38.738Z","createdAt":"2026-03-25T11:21:38.738Z","url":"/api/media/file/Role_Overview_Page.png","thumbnailURL":null,"filename":"Role_Overview_Page.png","mimeType":"image/png","filesize":396501,"width":2940,"height":1666,"focalX":50,"focalY":50},{"id":148,"alt":"Role add page CodeZero","href":null,"updatedAt":"2026-03-25T11:21:38.691Z","createdAt":"2026-03-25T11:21:38.691Z","url":"/api/media/file/Role_Add_Page.png","thumbnailURL":null,"filename":"Role_Add_Page.png","mimeType":"image/png","filesize":338014,"width":2940,"height":1666,"focalX":50,"focalY":50},{"id":149,"alt":"Role permission page CodeZero","href":null,"updatedAt":"2026-03-25T11:21:38.647Z","createdAt":"2026-03-25T11:21:38.647Z","url":"/api/media/file/Role_Permission_Page.png","thumbnailURL":null,"filename":"Role_Permission_Page.png","mimeType":"image/png","filesize":613737,"width":2940,"height":1666,"focalX":50,"focalY":50},{"id":150,"alt":"Member overview page CodeZero","href":null,"updatedAt":"2026-03-25T11:13:20.805Z","createdAt":"2026-03-25T11:13:20.805Z","url":"/api/media/file/Member_Overview_Page.png","thumbnailURL":null,"filename":"Member_Overview_Page.png","mimeType":"image/png","filesize":390811,"width":2940,"height":1668,"focalX":50,"focalY":50},{"id":151,"alt":"Member remove feature CodeZero","href":null,"updatedAt":"2026-03-25T11:13:20.787Z","createdAt":"2026-03-25T11:13:20.787Z","url":"/api/media/file/Member_Remove_Feature.png","thumbnailURL":null,"filename":"Member_Remove_Feature.png","mimeType":"image/png","filesize":354065,"width":2940,"height":1664,"focalX":50,"focalY":50},{"id":152,"alt":"Member assign roles feature CodeZero","href":null,"updatedAt":"2026-03-25T11:13:20.769Z","createdAt":"2026-03-25T11:13:20.769Z","url":"/api/media/file/Member_Assign_Roles_Feature.png","thumbnailURL":null,"filename":"Member_Assign_Roles_Feature.png","mimeType":"image/png","filesize":379400,"width":2940,"height":1664,"focalX":50,"focalY":50},{"id":153,"alt":"Member add feature CodeZero","href":null,"updatedAt":"2026-03-25T11:13:20.742Z","createdAt":"2026-03-25T11:13:20.742Z","url":"/api/media/file/Member_Add_Feature.png","thumbnailURL":null,"filename":"Member_Add_Feature.png","mimeType":"image/png","filesize":350024,"width":2940,"height":1666,"focalX":50,"focalY":50},{"id":154,"alt":"Project overview page CodeZero","href":null,"updatedAt":"2026-03-25T11:05:42.234Z","createdAt":"2026-03-25T11:05:42.234Z","url":"/api/media/file/Project_Overview_Feature.png","thumbnailURL":null,"filename":"Project_Overview_Feature.png","mimeType":"image/png","filesize":330250,"width":2940,"height":1666,"focalX":50,"focalY":50},{"id":155,"alt":"Create project in CodeZero","href":null,"updatedAt":"2026-03-25T11:05:01.102Z","createdAt":"2026-03-25T11:05:01.102Z","url":"/api/media/file/Create_Project_Feature.png","thumbnailURL":null,"filename":"Create_Project_Feature.png","mimeType":"image/png","filesize":378671,"width":2940,"height":1666,"focalX":50,"focalY":50},{"id":156,"alt":"Logistic automation workflow GLS CodeZero","href":null,"updatedAt":"2026-03-25T10:05:48.175Z","createdAt":"2026-03-25T10:05:48.175Z","url":"/api/media/file/Logistic_Use-Case-1.png","thumbnailURL":null,"filename":"Logistic_Use-Case-1.png","mimeType":"image/png","filesize":113308,"width":1920,"height":1080,"focalX":50,"focalY":50},{"id":157,"alt":"Discord bot automation CodeZero","href":null,"updatedAt":"2026-03-25T10:05:48.152Z","createdAt":"2026-03-25T10:05:48.152Z","url":"/api/media/file/Chatbot_Use-Case-1.png","thumbnailURL":null,"filename":"Chatbot_Use-Case-1.png","mimeType":"image/png","filesize":74140,"width":1920,"height":1080,"focalX":50,"focalY":50},{"id":158,"alt":"AI Use Case ChatGPT MCP Claude CodeZero","href":null,"updatedAt":"2026-03-25T10:05:48.123Z","createdAt":"2026-03-25T10:05:48.123Z","url":"/api/media/file/AI_Use-Case-1.png","thumbnailURL":null,"filename":"AI_Use-Case-1.png","mimeType":"image/png","filesize":126673,"width":1920,"height":1080,"focalX":50,"focalY":50},{"id":159,"alt":"Blog sample Image","href":null,"updatedAt":"2026-03-07T05:59:34.732Z","createdAt":"2026-03-07T05:59:34.731Z","url":"/api/media/file/blog-sample-image.jpg","thumbnailURL":null,"filename":"blog-sample-image.jpg","mimeType":"image/jpeg","filesize":75240,"width":864,"height":576,"focalX":50,"focalY":50},{"id":160,"alt":"Marius Ahsmus Bild","href":null,"updatedAt":"2026-03-07T05:28:39.443Z","createdAt":"2026-03-07T05:15:45.957Z","url":"/api/media/file/NDOLqYAv_400x400.jpg","thumbnailURL":null,"filename":"NDOLqYAv_400x400.jpg","mimeType":"image/jpeg","filesize":28513,"width":400,"height":400,"focalX":50,"focalY":50},{"id":161,"alt":"GLS Logo","href":"https://gls-group.com/","updatedAt":"2026-02-25T11:12:48.228Z","createdAt":"2026-02-25T11:08:24.824Z","url":"/api/media/file/gls_logo.png","thumbnailURL":null,"filename":"gls_logo.png","mimeType":"image/png","filesize":19352,"width":960,"height":337,"focalX":50,"focalY":50}]

export/pages.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

media/og-image.png

980 KB
Loading

package-lock.json

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"migrate": "payload migrate",
1313
"migrate:create": "payload migrate:create",
1414
"migrate:status": "payload migrate:status",
15+
"generate:importmap": "payload generate:importmap",
1516
"lint": "next lint",
1617
"knip": "knip",
1718
"generate": "payload generate:types",

public/og-image.png

980 KB
Loading

scripts/import-data.ts

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,11 @@ type ImportedBlogDocument = {
282282
} | number | string | null
283283
id?: number | string
284284
meta?: {
285+
title?: Record<string, string | null> | null
285286
description?: Record<string, string | null> | null
287+
image?: {
288+
id?: number | string
289+
} | number | string | null
286290
keywords?: Record<string, string | null> | null
287291
} | null
288292
ogImage?: {
@@ -572,6 +576,27 @@ const createImportReq = async (payload: PayloadInstance, importUser: ImportUser,
572576
return createLocalReq({ locale, user: importUser }, payload)
573577
}
574578

579+
const mapImportedBlogMetaForLocale = (
580+
doc: ImportedBlogDocument,
581+
locale: "en" | "de",
582+
mediaIDMap: Map<string, number | string>
583+
) => {
584+
const title = doc.meta?.title?.[locale] ?? doc.title?.[locale] ?? undefined
585+
const description = doc.meta?.description?.[locale] ?? undefined
586+
const imageSource = doc.meta?.image ?? doc.ogImage ?? doc.twitterImage ?? doc.heroImage
587+
const image = remapKnownRelationshipID(normalizeRelationshipID(imageSource), mediaIDMap)
588+
589+
if (!title && !description && image === undefined) {
590+
return undefined
591+
}
592+
593+
return {
594+
description,
595+
image,
596+
title,
597+
}
598+
}
599+
575600
const syncLocalizedDocument = async (
576601
payload: PayloadInstance,
577602
importUser: ImportUser,
@@ -895,27 +920,15 @@ const importBlogCollection = async (
895920
createdAt: doc.createdAt,
896921
heroImage: remapKnownRelationshipID(normalizeRelationshipID(doc.heroImage), mediaIDMap),
897922
id: normalizeNumericID(doc.id),
898-
meta: doc.meta
899-
? {
900-
description: doc.meta.description?.en ?? undefined,
901-
keywords: doc.meta.keywords?.en ?? undefined,
902-
}
903-
: undefined,
904-
ogImage: remapKnownRelationshipID(normalizeRelationshipID(doc.ogImage), mediaIDMap),
923+
meta: mapImportedBlogMetaForLocale(doc, "en", mediaIDMap),
905924
shortDescription: doc.shortDescription?.en ?? undefined,
906925
slug: doc.slug ?? "",
907926
title: doc.title?.en ?? "",
908-
twitterImage: remapKnownRelationshipID(normalizeRelationshipID(doc.twitterImage), mediaIDMap),
909927
updatedAt: doc.updatedAt,
910928
}),
911929
buildGermanData: (doc) => ({
912930
content: doc.content?.de ? mapBlogContentForImport(doc.content.de, mediaIDMap) : undefined,
913-
meta: doc.meta
914-
? {
915-
description: doc.meta.description?.de ?? undefined,
916-
keywords: doc.meta.keywords?.de ?? undefined,
917-
}
918-
: undefined,
931+
meta: mapImportedBlogMetaForLocale(doc, "de", mediaIDMap),
919932
shortDescription: doc.shortDescription?.de ?? undefined,
920933
title: doc.title?.de ?? "",
921934
}),
@@ -1021,7 +1034,7 @@ const formatImportError = (error: unknown) => {
10211034
return String(error)
10221035
}
10231036

1024-
const cause = error.cause as
1037+
const cause = (error as Error & { cause?: unknown }).cause as
10251038
| {
10261039
code?: string
10271040
column?: string

src/app/(landing)/[locale]/about-us/page.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,16 @@ import { Aurora } from "@/components/ui/Aurora"
44
import { LandingContainer } from "@/components/ui/LandingContainer"
55
import { MarkdownLayoutBlock, getLandingPage, getTeamMembers } from "@/lib/cms"
66
import { isSupportedLocale } from "@/lib/i18n"
7+
import { getLandingPageMetadata } from "@/lib/pageMetadata"
78
import { convertLexicalToHTML } from "@payloadcms/richtext-lexical/html"
9+
import type { Metadata } from "next"
810
import { notFound } from "next/navigation"
911

12+
export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }): Promise<Metadata> {
13+
const { locale } = await params
14+
return getLandingPageMetadata("about-us", locale)
15+
}
16+
1017
export default async function AboutPage({ params }: { params: Promise<{ locale: string }> }) {
1118
const { locale } = await params
1219
if (!isSupportedLocale(locale)) notFound()

0 commit comments

Comments
 (0)