Next.js Discord

Discord Forum

Data mutation on SSG page

Unanswered
Asian paper wasp posted this in #help-forum
Open in Discord
Asian paper waspOP
I believe this means I will not be able to make use of Server Actions, as I don't want the entire page to be dynamically generated simply because of a small feature.

What I'm trying to do: A like button with a like count, where a user can press the like button, and the count is expected to be increased by 1 (ignore the UI part as that's just a POC).

What I'm doing:
// src/app/blog/[slug]/page.tsx

const metadata = await kv.hgetall<{ like: number }>(
  `blog:metadata:${blog.id}`,
);

<Like count={metadata?.like} />


// like.tsx
'use client';

const router = useRouter();

<button 
  onClick={async () => {
    await fetch(`/api/blog/${id}/likes`, {
      method: 'POST',
    });
    router.refresh();
  }}
>
  like
</button>
<p>{count}</p>



// src/app/api/blog/[id]/likes/route.ts

import { kv } from '@vercel/kv';
import { revalidatePath } from 'next/cache';
import { NextRequest, NextResponse } from 'next/server';

export const POST = async (
  _: NextRequest,
  { params }: { params: { id: string } },
) => {
  await kv.hincrby(`blog:metadata:${params.id}`, 'like', 1);
  revalidatePath('/blog/[slug]');

  return NextResponse.json({});
};


My questions:

1. Is there a better way to do it?
2. If yes, how?
p.s. I've thought of using React Query

17 Replies

Your page cannot be static if it depends on data that changes randomly (sometimes quickly) overtime.
- You need a server to do a new server render on mutations. However, it can use revalidation instead of being totally dynamic, as you are demonstrating
- However note that revalidatePath cannot invalidate a specific dynamic page, here it will invalidate all your blog posts not just one. I think revalidateTag could work but you can only tag "fetch" calls, never tried it.
So if it's just about a like button, that is inherently dynamic but within a very static page, make it a client component and use an API route
Until revalidation of a specific dynamic page is possible
@Eric Burel So if it's just about a like button, that is inherently dynamic but within a very static page, make it a client component and use an API route
Asian paper waspOP
Is that mean at the current stage, I should make use of RQ or SWR and follow their guide on SSR for this? Like you said, I would assume the mutation happens within a client component.
I am not sure SSR would be involved but yeah I would use a client component here
server components are still beta, and the app router is still young
see https://github.com/vercel/next.js/discussions/54075#discussioncomment-6793417 for more details about the cache thing if you want to invalidae just one page it's possible with an experimental API
but you are entering the bleeding edge
the bleeding part is no joke
I've asked the question and the ability to revalidate one specific page is on its way, it was implemented just last month: https://github.com/vercel/next.js/pull/53321
so your initial approach is fine in theory, except you'd replace "blug/[slug]" by "blog/the right id here"
and this means you have to run a server (not "next export" or "output":"export" in the new version) but you can still consider the content static (in the sense that it only rerender if there is a mutation, otherwise it never rerenders)
Asian paper waspOP
Hmm, I don't really need that feature right now and I've developed a PC with React Query.
May be I should wait for longer for unstable_cache and server actions to be more mature
Thanks though