Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for custom blog url routing, update blog tag filtering, delete /blog/tag/[tagId] route #1797

Merged
merged 1 commit into from
Dec 23, 2024
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
2 changes: 2 additions & 0 deletions core/app/[locale]/(default)/blog/[blogId]/page-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const BlogPageQuery = graphql(
site {
content {
blog {
name
path
post(entityId: $entityId) {
author
htmlBody
Expand Down
9 changes: 5 additions & 4 deletions core/app/[locale]/(default)/blog/[blogId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ export default async function Blog({ params }: Props) {
const format = await getFormatter();

const data = await getBlogPageData({ entityId: Number(blogId) });
const blog = data?.content.blog;
const blogPost = data?.content.blog?.post;

if (!blogPost) {
if (!blogPost || !blog) {
return notFound();
}

Expand All @@ -52,8 +53,8 @@ export default async function Blog({ params }: Props) {
href: '/',
},
{
label: 'Blog',
href: '/blog',
label: blog.name,
href: blog.path,
},
{
label: blogPost.name,
Expand All @@ -70,7 +71,7 @@ export default async function Blog({ params }: Props) {
tags={blogPost.tags.map((tag) => ({
label: tag,
link: {
href: `/blog/tag/${tag}`,
href: `${blog.path}?tag=${tag}`,
},
}))}
title={blogPost.name}
Expand Down
17 changes: 9 additions & 8 deletions core/app/[locale]/(default)/blog/page-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const BlogQuery = graphql(`
blog {
name
description
path
}
}
}
Expand Down Expand Up @@ -52,14 +53,14 @@ const BlogPostsPageQuery = graphql(
[BlogPostCardFragment, PaginationFragment],
);

interface BlogPostsFiltersInput {
tagId?: string;
export interface BlogPostsFiltersInput {
tag: string | null;
}

interface Pagination {
limit?: number;
before?: string;
after?: string;
limit: number;
before: string | null;
after: string | null;
}

export const getBlog = cache(async () => {
Expand All @@ -72,8 +73,8 @@ export const getBlog = cache(async () => {
});

export const getBlogPosts = cache(
async ({ tagId, limit = 9, before, after }: BlogPostsFiltersInput & Pagination) => {
const filterArgs = tagId ? { filters: { tags: [tagId] } } : {};
async ({ tag, limit = 9, before, after }: BlogPostsFiltersInput & Pagination) => {
const filterArgs = tag ? { filters: { tags: [tag] } } : {};
const paginationArgs = before ? { last: limit, before } : { first: limit, after };

const response = await client.fetch({
Expand Down Expand Up @@ -103,7 +104,7 @@ export const getBlogPosts = cache(
alt: post.thumbnailImage.altText,
}
: undefined,
href: `/blog/${post.entityId}`,
href: post.path,
title: post.name,
})),
};
Expand Down
30 changes: 22 additions & 8 deletions core/app/[locale]/(default)/blog/page.tsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,57 @@
import type { Metadata } from 'next';
import { notFound } from 'next/navigation';
import { SearchParams } from 'nuqs';
import { createSearchParamsCache, parseAsInteger, parseAsString } from 'nuqs/server';

import { FeaturedBlogPostList } from '@/vibes/soul/sections/featured-blog-post-list';
import { defaultPageInfo, pageInfoTransformer } from '~/data-transformers/page-info-transformer';

import { getBlog, getBlogMetaData, getBlogPosts } from './page-data';

type SearchParams = Record<string, string | string[] | undefined>;

interface Props {
params: Promise<{ locale: string }>;
searchParams: Promise<SearchParams>;
}

const defaultPostLimit = 9;

const searchParamsCache = createSearchParamsCache({
tag: parseAsString,
before: parseAsString,
after: parseAsString,
limit: parseAsInteger.withDefault(defaultPostLimit),
});

export async function generateMetadata(): Promise<Metadata> {
return await getBlogMetaData();
}

async function listBlogPosts(searchParamsPromise: Promise<SearchParams>) {
const searchParams = await searchParamsPromise;
const blogPosts = await getBlogPosts(searchParams);
const searchParamsParsed = searchParamsCache.parse(await searchParamsPromise);
const blogPosts = await getBlogPosts(searchParamsParsed);
const posts = blogPosts?.posts ?? [];

return posts;
}

async function getPaginationInfo(searchParamsPromise: Promise<SearchParams>) {
const searchParams = await searchParamsPromise;
const blogPosts = await getBlogPosts(searchParams);
const searchParamsParsed = searchParamsCache.parse(await searchParamsPromise);
const blogPosts = await getBlogPosts(searchParamsParsed);

return pageInfoTransformer(blogPosts?.pageInfo ?? defaultPageInfo);
}

export default async function Blog(props: Props) {
const searchParamsParsed = searchParamsCache.parse(await props.searchParams);
const { tag } = searchParamsParsed;
const blog = await getBlog();

if (!blog) {
return notFound();
}

const tagCrumb = tag ? [{ label: tag, href: '#' }] : [];

return (
<FeaturedBlogPostList
breadcrumbs={[
Expand All @@ -47,9 +60,10 @@ export default async function Blog(props: Props) {
href: '/',
},
{
label: 'Blog',
href: '#',
label: blog.name,
href: tag ? blog.path : '#',
},
...tagCrumb,
]}
description={blog.description}
paginationInfo={getPaginationInfo(props.searchParams)}
Expand Down
67 changes: 0 additions & 67 deletions core/app/[locale]/(default)/blog/tag/[tagId]/page.tsx

This file was deleted.

1 change: 1 addition & 0 deletions core/components/blog-post-card/fragment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const BlogPostCardFragment = graphql(`
author
entityId
name
path
plainTextSummary
publishedDate {
utc
Expand Down
15 changes: 15 additions & 0 deletions core/middlewares/with-routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ const GetRouteQuery = graphql(`
... on Brand {
entityId
}
... on BlogPost {
entityId
}
}
}
}
Expand Down Expand Up @@ -152,6 +155,8 @@ const NodeSchema = z.union([
z.object({ __typename: z.literal('ContactPage'), id: z.string() }),
z.object({ __typename: z.literal('NormalPage'), id: z.string() }),
z.object({ __typename: z.literal('RawHtmlPage'), id: z.string() }),
z.object({ __typename: z.literal('Blog'), id: z.string() }),
z.object({ __typename: z.literal('BlogPost'), entityId: z.number() }),
]);

const RouteSchema = z.object({
Expand Down Expand Up @@ -330,6 +335,16 @@ export const withRoutes: MiddlewareFactory = () => {
});
}

case 'Blog': {
url = `/${locale}/blog`;
break;
}

case 'BlogPost': {
url = `/${locale}/blog/${node.entityId}`;
break;
}

default: {
const { pathname } = new URL(request.url);

Expand Down
Loading