Skip to content

ClerkProvider Should Not Force All Children to Render Dynamically #1746

@magnusriga

Description

@magnusriga

Preliminary Checks

Reproduction / Replay Link

Na

Publishable key

na

Description

Posting this as a bug, even though it is technically a feature, due to its severity.

Currently, the ClerkProvider forces all child routes to render dynamically.

The documentation states that you can move the provider further down the component tree, to address the issue.

Unfortunately, that is not a viable solution in many cases.

Typically, an app has several protected routes, where a common component (like a navbar) is shown on each route, and that component needs to know whether a user is logged in (e.g. to show certain links). The other components in a route might benefit massively from being statically (build time) rendered.

If certain data fetches are slow, not being able to do the fetch/render build-time, might break the application's usability entirely.

In other words, taking away static rendering across all provider children will drastically impact the performance of the application and in certain cases render it useless.

ClerkProvider states that it needs dynamic routes because it uses headers() (and/or cookies()), which are built-in next functions that opt the entire route they appear in into dynamic rendering.

It is my understanding, and I might be wrong, that those functions can only be used in server components. They read a http request's headers or cookies. As such, they do not make sense, client side.

So, given how those functions work, why would we need to dynamically render all children of the ClerkProvider, if none of those children use server side auth functionality.

As an example, if the navbar mentioned above is a client component, and middleware is used to protect routes, I do not see why headers() or cookies() are needed at all.

To test this, I added the Next.js Route Segment Config option to the top of the top-most layout: export const dynamic='force-static'. This turned the full app back to static rendering, even though it used the ClerkProvider around the top-level layout, has a navbar client component that checks if user is logged in, and has all routes protected with middleware. It still works, both the auth and the app.

So, my questions are:

  1. Could you keep static rendering as the default, just as Next does, and only opt routes that need headers() into dynamic rendering?

  2. What are the consequences of my solution? Will it work as intended, in the example I gave (where no server side auth functions are used)?

Environment

Latest Clerk and Next is used

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions