Dynamic route [id], cached by default

import NavLink from '@/components/NavLink/NavLink';

import { api } from '@/utils/api';

export const metadata = {
  title: 'Dynamic Simple',
};

const PostPage = async ({ params }: { params: { id: string } }) => {
  const [post] = await api.post(params.id);
  const [image] = await api.images();

  return (
    <div>
      <article>
        <h2>{post.title}</h2>

        <p>{post.body}</p>
        <div className="grid">
          <img src={image} alt="dog" width={400} />
        </div>
        <NavLink href={`/users/${post.userId}`} className={'secondary'}>
          Author Page
        </NavLink>
      </article>
    </div>
  );
};

export default PostPage;

export async function generateStaticParams() {
  const [posts] = await api.posts();

  return posts.slice(0, 10).map((post) => {
    return {
      id: String(post.id),
    };
  });
}
import { proxyFetch } from './proxyFetch';

import type { Post, User } from '@/app/global';

const fetchData = async (url: string, options?: RequestInit) => {
  const result = await proxyFetch.fetch(url, options).catch(console.error);
  return { data: result?.data, counter: result?.counter };
};

export const api = {
  post: async (id: string, options?: RequestInit) => {
    let updatedId = id;

    if (id === 'random') {
      updatedId = String(Math.round(Math.random() * 100));
    }

    if (id === 'best') {
      updatedId = String(99);
    }

    if (id === 'dynamic') {
      updatedId = String(13);
    }

    const result = await fetchData(`/posts/${updatedId}`, options);

    return [result?.data, result?.counter] as [Post, number];
  },

  posts: async () => {
    const result = await fetchData('/posts');
    return [result.data, result.counter] as [Post[], number];
  },

  user: async (id: string) => {
    const result = await fetchData(`/users/${id}`);
    return [result.data, result.counter] as [User, number];
  },

  users: async () => {
    const result = await fetchData('/users');
    return [result.data, result.counter] as [User[], number];
  },

  images: async (options?: RequestInit) => {
    const result = await fetchData('/images', options);

    return [result.data, result.counter] as [string, number];
  },
};