Next.js Discord

Discord Forum

SSR with dynamic options

Unanswered
Northeast Congo Lion posted this in #help-forum
Open in Discord
Northeast Congo LionOP
I have a product page. I want it to be rendered incrementally server side (ISR). However there are a few parts of the page that I want to render differently if the creator of the product is logged in.

For example item description. 99 percent of the time it just the description but if the creator is logged in it should show a few buttons to edit the description.

Now the entire product page is wrapped in a context provider for the product info. So I think this means i cant really use SSR here as the context uses state and other stuff. So maybe that was not the correct solution. I did this so all these dynamic components that will show only for the creator can share the same product data.

What I'd like is the basic product page to be rendered with ISR and then if the user is the creator dynamic alternative components can be rendered.

how can I achieve this? while keeping the basic product page fully server side rendered

13 Replies

Northeast Congo LionOP
hmm not a soul lol
American black bear
The children of <ContextProvider /> are not automatically turned into client components so your page should still be rendered on server.
American black bear
// your context provider which is a client component and uses hooks 
"use client"

export const MyContext = createContext();

export default function ContextProvider({ children }) {
  const [state, setState] = useState("initial value");

  return (
    <MyContext.Provider value={{ state, setState }}>
      {children}
    </MyContext.Provider>
  );
}


export default function Page() {
  return (
    <ContextProvider>
      <div>This code runs on server.</div>
    </ContextProvider>
  );
}
Checkout this example
@American black bear tsx // your context provider which is a client component and uses hooks "use client" export const MyContext = createContext(); export default function ContextProvider({ children }) { const [state, setState] = useState("initial value"); return ( <MyContext.Provider value={{ state, setState }}> {children} </MyContext.Provider> ); } tsx export default function Page() { return ( <ContextProvider> <div>This code runs on server.</div> </ContextProvider> ); }
Northeast Congo LionOP
so how do i do one page for the creator of the product and another entirely different page for everyone else?

i have a context around this route somewhere higher

if you are the creator of this product render <CreatorProductpage /> which is a client page

if you are not the creator of this product render <ISRBasedProductPage />

And yet ISR can still build all the routes for those on the server?
American black bear
if I am understanding you correctly you just want to display for example edit button on description of product if the user is the admin or owner of post?
if this is the case you should do something like this:

1. Create page level context containing product information (product name, product description, product owner, etc.)
2. Create components for common elements (ProductTitle, ProductDescription, etc.)
3. Inside individual components use context to check if the user is owner and modify them accordingly
Northeast Congo LionOP
no i want a fully different page
American black bear
then just use a different route
Northeast Congo LionOP
accessible at the same route...
function page({}: Props) {
  return (
    <ProdsPageWrapper params={{ slug }}>
        <StaticPage params={{ slug }} />
    </ProdsPageWrapper>
  )
}


so far i think this might work? page wrapper has the logic for user, if it finds a user it renders something else, if it doesnt it render children, i'm just not positive all those static pages will be built at build time or not and if ISR works throug this
American black bear
a quick check should do the trick:

// url /product/123
export default async function ProductPage() {
  const user = await getUser()
  const product = await getProduct()

  if (user.id == product.creator) redirect("/product/123/edit")
  

  // ...
}

// or on same route

export default async function ProductPage() {
  const user = await getUser()
  const product = await getProduct()

  if (user.id == product.creator) {
    return <EditProductPage product={product} />
  }

  return // ... your product page
}
Northeast Congo LionOP
well the filled in circle is new so thats maybe good
├ ƒ /news/[slug]                                                  205 B            95 kB
├ ○ /partner                                                      127 kB          344 kB
├ ○ /placeholder                                                  231 B          88.2 kB
├ ○ /privacy                                                      4.81 kB         184 kB
├ ● /prods/[slug]                                                 1.41 kB         118 kB
├ ○ /products