I'm currently developing a blog using AWS Amplify Gen 2 and GraphQL for a Next.js 14 project with TypeScript. As part of my application, I need to fetch specific data based on the URL path name. Here's how I've approached it:
My approach involves utilizing a component called Article:
'use client';
import { usePathname } from "next/navigation";
export default function Article() {
const slug = usePathname().split('/').pop();
return slug;
}
Within my app, I have a page.tsx file located at app/articles/[slug]:
import type { Schema } from '@/amplify/data/resource';
import { generateClient } from 'aws-amplify/data';
import Article from '@/components/article/article';
const client = generateClient<Schema>();
async function fetchPosts() {
const { data: posts } = await client.models.Posts.list();
return posts;
}
export default async function ArticlePage() {
const posts = await fetchPosts();
return (
// I aim to retrieve and display posts that match the slug value in the URL path
);
}
I am looking to modify ArticlePage so that it can fetch and present the posts that correspond to the slug value found in the URL path. How can this be achieved?
The key details are: I'm working with Next.js 14 and TypeScript.
The client.models.Posts.list()
function retrieves all posts, but I require them to be filtered based on the slug value from the URL path.
EDIT:
The code snippet below accomplishes the task, yet instead of a static String, I want the slug to derive from the URL path ("/articles/my-first-post" or "/articles/my-second-post").
import type { Schema } from '@/amplify/data/resource';
import { generateClient } from 'aws-amplify/data';
const client = generateClient<Schema>();
async function fetchPosts() {
const { data: posts, errors } = await client.models.Posts.list();
return posts;
}
export default async function Article() {
const slug = 'my-first-post'; // This should dynamically come from the URL path
const posts = await fetchPosts();
const filteredPosts = posts.filter(post => post.slug === slug);
return (
<div>
{filteredPosts.map(post => (
<div key={post.createdAt}>
<h2>{post.title}</h2>
<p>{new Date(post.createdAt).toLocaleDateString()}</p>
<p>{post.content}</p>
</div>
))}
</div>
);
}