blitz-js / blitz-js/blitz

Turn Page.suppressFirstRenderFlicker and authenticate into React components

Open
#3,029 4 comments 0 reactions 0 assignees View on GitHub
kind/feature-change status/ready-to-work-on
Dominant language
TypeScript
Stars
14.1k
Forks
803
PR merge metrics
No merged PRs in 30d

Description

### What do you want and why?

(Edited from my thread on Discord)

It would be beneficial to convert page options like suppressFirstRenderFlicker and authenticate into React components. Having options as `Page.xxx = x` restricts you to configuring the option upfront and doesn't mesh with how developers expect to compose features in React components.

Benefits:
- no learning curve, React devs are familiar with components already
- config options become props, allowing you to e.g. set the redirectTo path with a dynamic expression at render-time
- you can attach `` or `` anywhere in the component graph, such as in a `` to automatically configure multiple pages
- Components are the de facto unit of composition in React; the more things that are components, the better
- backwards compatible by rendering the components where they appear in the main wrapper now
- main wrapper component stops violating Single Responsibility Principle
- `` being a component means it can be rendered conditionally, which makes it more flexible for devs to use

### Possible implementation(s)

I think it would mostly be a matter of moving the existing logic out of the main wrapper and into separate components, or via `useLayoutEffect()` and `createPortal()` to access the app root and initial paint regardless of where the component sits in the component graph.

SuppressFirstRenderFlicker would probably want to have an assertion when NODE_ENV=development to issue a warning if it gets mounted after the initial render, telling the developer to move it higher up in the component graph.

### Additional context

Comparison:

```tsx
// current
const Layout: BlitzLayout = ({ children }) => {
return

{children}

}
// I honestly didn't know these options even worked on layouts,
// and I'm probably not the only one who didn't realize this
Layout.authenticate = {redirectTo: '/login'}
Layout.suppressFirstRenderFlicker = true
```

vs

```tsx
// proposal
const Layout: BlitzLayout = ({ children }) => {
return <>

{children}




}
```

cc @flybayer

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.