Skip to content

Commit 173b2f7

Browse files
authored
Merge pull request #271 from code0-tech/feat/improve-footer
Feat/improve footer
2 parents 6335b7d + 2243549 commit 173b2f7

66 files changed

Lines changed: 5459 additions & 1477 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

package-lock.json

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

package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@
1313
"migrate:create": "payload migrate:create",
1414
"migrate:status": "payload migrate:status",
1515
"generate:importmap": "payload generate:importmap",
16-
"lint": "next lint",
16+
"lint": "npm run typecheck",
17+
"typecheck": "tsc --noEmit",
1718
"knip": "node --import tsx ./node_modules/knip/bin/knip.js",
1819
"generate": "payload generate:types"
1920
},
2021
"dependencies": {
22+
"@base-ui/react": "^1.5.0",
2123
"@c15t/nextjs": "^2.1.0",
2224
"@c15t/scripts": "^2.1.0",
2325
"@code0-tech/pictor": "^0.7.2",
@@ -29,6 +31,7 @@
2931
"@payloadcms/plugin-seo": "3.84.1",
3032
"@payloadcms/richtext-lexical": "3.84.1",
3133
"@tabler/icons-react": "3.41.1",
34+
"class-variance-authority": "^0.7.1",
3235
"clsx": "^2.1.1",
3336
"graphql": "^16.14.0",
3437
"knip": "^6.14.1",
@@ -40,8 +43,10 @@
4043
"react": "^19.2.6",
4144
"react-dom": "^19.2.6",
4245
"sass": "^1.100.0",
46+
"shadcn": "^4.8.0",
4347
"sharp": "^0.34.5",
4448
"tailwind-merge": "^3.6.0",
49+
"tw-animate-css": "^1.4.0",
4550
"web-haptics": "^0.0.6"
4651
},
4752
"devDependencies": {

public/sitemap.xml

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,30 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
3-
<url><loc>http://localhost:3000</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority><xhtml:link rel="alternate" hreflang="en" href="http://localhost:3000/en"/><xhtml:link rel="alternate" hreflang="de" href="http://localhost:3000/de"/></url>
4-
<url><loc>http://localhost:3000/en</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>weekly</changefreq><priority>1</priority></url>
5-
<url><loc>http://localhost:3000/en/about-us</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
6-
<url><loc>http://localhost:3000/en/actions</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
7-
<url><loc>http://localhost:3000/en/blog</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
8-
<url><loc>http://localhost:3000/en/community-edition</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
9-
<url><loc>http://localhost:3000/en/contact</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
10-
<url><loc>http://localhost:3000/en/enterprise-edition</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
11-
<url><loc>http://localhost:3000/en/features</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
12-
<url><loc>http://localhost:3000/en/jobs</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
13-
<url><loc>http://localhost:3000/en/legal-notice</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
14-
<url><loc>http://localhost:3000/en/privacy</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
15-
<url><loc>http://localhost:3000/en/subscription</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
16-
<url><loc>http://localhost:3000/en/terms</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
17-
<url><loc>http://localhost:3000/de</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>weekly</changefreq><priority>1</priority></url>
18-
<url><loc>http://localhost:3000/de/about-us</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
19-
<url><loc>http://localhost:3000/de/actions</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
20-
<url><loc>http://localhost:3000/de/blog</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
21-
<url><loc>http://localhost:3000/de/community-edition</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
22-
<url><loc>http://localhost:3000/de/contact</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
23-
<url><loc>http://localhost:3000/de/enterprise-edition</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
24-
<url><loc>http://localhost:3000/de/features</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
25-
<url><loc>http://localhost:3000/de/jobs</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
26-
<url><loc>http://localhost:3000/de/legal-notice</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
27-
<url><loc>http://localhost:3000/de/privacy</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
28-
<url><loc>http://localhost:3000/de/subscription</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
29-
<url><loc>http://localhost:3000/de/terms</loc><lastmod>2026-05-13T05:17:48.888Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
3+
<url><loc>http://localhost:3000</loc><lastmod>2026-05-24T07:40:24.625Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority><xhtml:link rel="alternate" hreflang="en" href="http://localhost:3000/en"/><xhtml:link rel="alternate" hreflang="de" href="http://localhost:3000/de"/></url>
4+
<url><loc>http://localhost:3000/en</loc><lastmod>2026-05-24T07:40:24.626Z</lastmod><changefreq>weekly</changefreq><priority>1</priority></url>
5+
<url><loc>http://localhost:3000/en/about-us</loc><lastmod>2026-05-24T07:40:24.626Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
6+
<url><loc>http://localhost:3000/en/actions</loc><lastmod>2026-05-24T07:40:24.626Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
7+
<url><loc>http://localhost:3000/en/blog</loc><lastmod>2026-05-24T07:40:24.626Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
8+
<url><loc>http://localhost:3000/en/community-edition</loc><lastmod>2026-05-24T07:40:24.626Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
9+
<url><loc>http://localhost:3000/en/contact</loc><lastmod>2026-05-24T07:40:24.626Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
10+
<url><loc>http://localhost:3000/en/enterprise-edition</loc><lastmod>2026-05-24T07:40:24.626Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
11+
<url><loc>http://localhost:3000/en/features</loc><lastmod>2026-05-24T07:40:24.626Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
12+
<url><loc>http://localhost:3000/en/jobs</loc><lastmod>2026-05-24T07:40:24.626Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
13+
<url><loc>http://localhost:3000/en/legal-notice</loc><lastmod>2026-05-24T07:40:24.626Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
14+
<url><loc>http://localhost:3000/en/privacy</loc><lastmod>2026-05-24T07:40:24.626Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
15+
<url><loc>http://localhost:3000/en/subscription</loc><lastmod>2026-05-24T07:40:24.626Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
16+
<url><loc>http://localhost:3000/en/terms</loc><lastmod>2026-05-24T07:40:24.626Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
17+
<url><loc>http://localhost:3000/de</loc><lastmod>2026-05-24T07:40:24.626Z</lastmod><changefreq>weekly</changefreq><priority>1</priority></url>
18+
<url><loc>http://localhost:3000/de/about-us</loc><lastmod>2026-05-24T07:40:24.626Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
19+
<url><loc>http://localhost:3000/de/actions</loc><lastmod>2026-05-24T07:40:24.626Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
20+
<url><loc>http://localhost:3000/de/blog</loc><lastmod>2026-05-24T07:40:24.626Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
21+
<url><loc>http://localhost:3000/de/community-edition</loc><lastmod>2026-05-24T07:40:24.626Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
22+
<url><loc>http://localhost:3000/de/contact</loc><lastmod>2026-05-24T07:40:24.626Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
23+
<url><loc>http://localhost:3000/de/enterprise-edition</loc><lastmod>2026-05-24T07:40:24.626Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
24+
<url><loc>http://localhost:3000/de/features</loc><lastmod>2026-05-24T07:40:24.626Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
25+
<url><loc>http://localhost:3000/de/jobs</loc><lastmod>2026-05-24T07:40:24.626Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
26+
<url><loc>http://localhost:3000/de/legal-notice</loc><lastmod>2026-05-24T07:40:24.626Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
27+
<url><loc>http://localhost:3000/de/privacy</loc><lastmod>2026-05-24T07:40:24.626Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
28+
<url><loc>http://localhost:3000/de/subscription</loc><lastmod>2026-05-24T07:40:24.626Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
29+
<url><loc>http://localhost:3000/de/terms</loc><lastmod>2026-05-24T07:40:24.626Z</lastmod><changefreq>weekly</changefreq><priority>0.7</priority></url>
3030
</urlset>

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

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,18 @@ import { TeamMemberCard } from "@/components/cards/TeamMemberCard"
22
import { MarkdownContent } from "@/components/blog/MarkdownContent"
33
import { Aurora } from "@/components/ui/Aurora"
44
import { LandingContainer } from "@/components/ui/LandingContainer"
5-
import { MarkdownLayoutBlock, getLandingPage, getTeamMembers } from "@/lib/cms"
6-
import { isSupportedLocale } from "@/lib/i18n"
7-
import { getLandingPageMetadata } from "@/lib/pageMetadata"
5+
import { createLandingMetadata, getPageLocale, type LocalePageParams } from "@/lib/appRoute"
6+
import { getLandingPage, getTeamMembers } from "@/lib/cms"
7+
import { findPageBlock } from "@/lib/pageBlocks"
88
import { convertLexicalToHTML } from "@payloadcms/richtext-lexical/html"
9-
import type { Metadata } from "next"
10-
import { notFound } from "next/navigation"
119

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-
17-
export default async function AboutPage({ params }: { params: Promise<{ locale: string }> }) {
18-
const { locale } = await params
19-
if (!isSupportedLocale(locale)) notFound()
10+
export const generateMetadata = createLandingMetadata("about-us")
2011

12+
export default async function AboutPage({ params }: { params: LocalePageParams }) {
13+
const locale = await getPageLocale(params)
2114
const aboutUsPage = await getLandingPage("about-us", locale)
2215
const teamMembers = await getTeamMembers(locale)
23-
const markdownBlock = aboutUsPage?.layout?.find((block): block is MarkdownLayoutBlock => block.blockType === "markdown") ?? null
16+
const markdownBlock = findPageBlock(aboutUsPage, "markdown")
2417
const contentHtml = markdownBlock
2518
? convertLexicalToHTML({ data: markdownBlock.content, disableContainer: true })
2619
: ""

src/app/(landing)/[locale]/actions/[slug]/page.tsx

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,19 @@ import { Aurora } from "@/components/ui/Aurora"
44
import { HapticButtonLink } from "@/components/ui/HapticButtonLink"
55
import { LandingContainer } from "@/components/ui/LandingContainer"
66
import { LinkButton } from "@/components/ui/LinkButton"
7-
import { getActionBySlug, getLandingPage, type ActionsLayoutBlock } from "@/lib/cms"
8-
import { isSupportedLocale } from "@/lib/i18n"
7+
import { getPageLocaleAndSlug, type LocaleSlugPageParams } from "@/lib/appRoute"
8+
import { getActionBySlug, getLandingPage } from "@/lib/cms"
99
import { getMediaUrl } from "@/lib/media"
10+
import { findPageBlock } from "@/lib/pageBlocks"
1011
import { createMetadata } from "@/lib/siteConfig"
1112
import type { Media } from "@/payload-types"
1213
import { IconArrowLeft, IconExternalLink } from "@tabler/icons-react"
1314
import type { Metadata } from "next"
1415
import Image from "next/image"
1516
import { notFound } from "next/navigation"
1617

17-
export default async function ActionDetailPage({ params }: { params: Promise<{ locale: string, slug: string }> }) {
18-
const { locale, slug } = await params
19-
if (!isSupportedLocale(locale)) notFound()
20-
if (!slug?.trim()) notFound()
21-
18+
export default async function ActionDetailPage({ params }: { params: LocaleSlugPageParams }) {
19+
const { locale, slug } = await getPageLocaleAndSlug(params)
2220
const action = await getActionBySlug(slug, locale)
2321
if (!action) notFound()
2422
const actionsPage = await getLandingPage("actions", locale)
@@ -29,7 +27,7 @@ export default async function ActionDetailPage({ params }: { params: Promise<{ l
2927
const functionDefs = action.functiondefinitions as Media | undefined
3028
const references = (action.references ?? []).filter((reference): reference is Exclude<typeof reference, number> => typeof reference !== "number")
3129
const tags = (action.tags ?? []).filter((tag): tag is string => Boolean(tag))
32-
const actionsBlock = actionsPage?.layout?.find((block): block is ActionsLayoutBlock => block.blockType === "actions") ?? null
30+
const actionsBlock = findPageBlock(actionsPage, "actions")
3331
const referencesLabel = actionsBlock?.referencesLabel ?? (locale === "de" ? "Referenzen" : "References")
3432

3533
return (
@@ -125,10 +123,10 @@ export default async function ActionDetailPage({ params }: { params: Promise<{ l
125123
)
126124
}
127125

128-
export async function generateMetadata({ params }: { params: Promise<{ locale: string, slug: string }> }): Promise<Metadata> {
126+
export async function generateMetadata({ params }: { params: LocaleSlugPageParams }): Promise<Metadata> {
129127
const { locale, slug } = await params
130-
if (!isSupportedLocale(locale)) return createMetadata()
131128
if (!slug?.trim()) return createMetadata()
129+
if (locale !== "de" && locale !== "en") return createMetadata()
132130

133131
const action = await getActionBySlug(slug, locale)
134132
if (!action) return createMetadata()

src/app/(landing)/[locale]/actions/page.tsx

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,19 @@
11
import { ActionsPageClient } from "@/components/ActionsPageClient"
22
import { Aurora } from "@/components/ui/Aurora"
33
import { LandingContainer } from "@/components/ui/LandingContainer"
4-
import { getActions, getLandingPage, type ActionsLayoutBlock } from "@/lib/cms"
5-
import { isSupportedLocale } from "@/lib/i18n"
6-
import { getLandingPageMetadata } from "@/lib/pageMetadata"
7-
import { Metadata } from "next"
8-
import { notFound } from "next/navigation"
4+
import { createLandingMetadata, getPageLocale, type LocalePageParams } from "@/lib/appRoute"
5+
import { getActions, getLandingPage } from "@/lib/cms"
6+
import { findPageBlock } from "@/lib/pageBlocks"
97

10-
export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }): Promise<Metadata> {
11-
const { locale } = await params
12-
return getLandingPageMetadata("actions", locale)
13-
}
14-
15-
export default async function ActionsPage({ params }: { params: Promise<{ locale: string }> }) {
16-
const { locale } = await params
17-
if (!isSupportedLocale(locale)) notFound()
8+
export const generateMetadata = createLandingMetadata("actions")
189

10+
export default async function ActionsPage({ params }: { params: LocalePageParams }) {
11+
const locale = await getPageLocale(params)
1912
const [actions, actionsPage] = await Promise.all([
2013
getActions(locale),
2114
getLandingPage("actions", locale),
2215
])
23-
const actionsBlock = actionsPage?.layout?.find((block): block is ActionsLayoutBlock => block.blockType === "actions") ?? null
16+
const actionsBlock = findPageBlock(actionsPage, "actions")
2417

2518
return (
2619
<>

src/app/(landing)/[locale]/blog/[slug]/page.tsx

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ import { InteractiveGridPattern } from "@/components/InteractiveGridPattern"
44
import { Aurora } from "@/components/ui/Aurora"
55
import { HapticButtonLink } from "@/components/ui/HapticButtonLink"
66
import { LandingContainer } from "@/components/ui/LandingContainer"
7-
import { getBlogPostBySlug, getLandingPage, type CtaLayoutBlock } from "@/lib/cms"
8-
import { isSupportedLocale } from "@/lib/i18n"
7+
import { getPageLocaleAndSlug, type LocaleSlugPageParams } from "@/lib/appRoute"
8+
import { getBlogPostBySlug, getLandingPage } from "@/lib/cms"
9+
import { findPageBlock } from "@/lib/pageBlocks"
910
import { createMetadata, resolveSiteUrl } from "@/lib/siteConfig"
1011
import { type Media } from "@/payload-types"
1112
import type { Metadata } from "next"
@@ -21,14 +22,10 @@ function getMediaUrl(value?: number | Media | null) {
2122
return new URL(value.url, resolveSiteUrl()).toString()
2223
}
2324

24-
export default async function Page({ params }: { params: Promise<{ locale: string, slug: string }> }) {
25-
const { locale, slug } = await params
26-
if (!isSupportedLocale(locale)) notFound()
27-
if (!slug?.trim()) notFound()
28-
25+
export default async function Page({ params }: { params: LocaleSlugPageParams }) {
26+
const { locale, slug } = await getPageLocaleAndSlug(params)
2927
const page = await getLandingPage("main", locale)
30-
const layout = page?.layout ?? []
31-
const ctaBlock = layout.find((block): block is CtaLayoutBlock => block.blockType === "cta") ?? null
28+
const ctaBlock = findPageBlock(page, "cta")
3229

3330
return (
3431
<>
@@ -83,10 +80,10 @@ export default async function Page({ params }: { params: Promise<{ locale: strin
8380
)
8481
}
8582

86-
export async function generateMetadata({ params }: { params: Promise<{ locale: string, slug: string }> }): Promise<Metadata> {
83+
export async function generateMetadata({ params }: { params: LocaleSlugPageParams }): Promise<Metadata> {
8784
const { locale, slug } = await params
88-
if (!isSupportedLocale(locale)) return createMetadata()
8985
if (!slug?.trim()) return createMetadata()
86+
if (locale !== "de" && locale !== "en") return createMetadata()
9087

9188
const post = await getBlogPostBySlug(slug, locale)
9289
if (!post) return createMetadata()

src/app/(landing)/[locale]/blog/page.tsx

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
1-
import { BlogBlock } from "@/blocks/BlogBlock"
21
import { BlogPageClient } from "@/components/blog/BlogPageClient"
32
import { Aurora } from "@/components/ui/Aurora"
43
import { LandingContainer } from "@/components/ui/LandingContainer"
4+
import { createLandingMetadata, getPageLocale, type LocalePageParams } from "@/lib/appRoute"
55
import { BlogLayoutBlock, getBlogPosts, getLandingPage } from "@/lib/cms"
6-
import { isSupportedLocale } from "@/lib/i18n"
7-
import { notFound } from "next/navigation"
86

97
const BLOG_PAGE_LABEL_FALLBACKS = {
108
de: {
119
viewOtherBlogsLabel: "Weitere Blogbeiträge",
1210
noPostsLabel: "Keine Blogbeiträge verfügbar.",
1311
loadMoreLabel: "Mehr laden",
14-
loadingLabel: "Laedt...",
12+
loadingLabel: "Lädt...",
1513
},
1614
en: {
1715
viewOtherBlogsLabel: "View other blog posts",
@@ -21,9 +19,10 @@ const BLOG_PAGE_LABEL_FALLBACKS = {
2119
},
2220
} as const
2321

24-
export default async function BlogPage({ params }: { params: Promise<{ locale: string }> }) {
25-
const { locale } = await params
26-
if (!isSupportedLocale(locale)) notFound()
22+
export const generateMetadata = createLandingMetadata("blog")
23+
24+
export default async function BlogPage({ params }: { params: LocalePageParams }) {
25+
const locale = await getPageLocale(params)
2726

2827
const [posts, blogPage] = await Promise.all([
2928
getBlogPosts(locale, { page: 1, limit: 10 }),

0 commit comments

Comments
 (0)