DEV Community

loading...
Cover image for Blitz.js + React Three Fiber == React Three Blitz?!

Blitz.js + React Three Fiber == React Three Blitz?!

c0d3t3k
React consultants
・Updated on ・4 min read

Blitz.js + React Three Fiber ==> React Three Blitz?

In order to celebrate the recent Blitz.js promotion to formal Beta,

we thought it might be fun to see how it integrates with one of our favorite frameworks, React Three Fiber. Introducing react-three-blitz!

What is Blitz.js?

If you haven't seen it yet, you owe it to yourself to checkout one of Brandon Bayer's (the founder and chief evangelist of Blitz.js) very thorough video introductions.

We are intrigued by blitz.js because it offers a compelling, uniquely integrated (Rails-like?) monolithic, full stack solution built using top tier open source components (React, Next.js, Prisma ORM, React Query, Passport.js Auth Strategies,etc.).

What is react-three-fiber?

To put it simply, r3f a React renderer for THREE.js for the web and react-native. THREE.js has been a gamechanger but we really feel that @0xca0a/@drcmda et al's react-three-fiber [and the Drei utilites!] takes it to the next level by wrapping THREE.js primitives, etc. to keep all of our 3D web dev concise and performant.

A lot of credit for this integration idea goes to @onireanud et al and his @pmndrs umbrella creation react-three-next. This excellent project introduces a compelling pattern, especially for integrating r3f and next.js.

Specifically, react-three-next uses a unified layout model containing a THREE.js/r3f canvas and a react DOM container overlaid on top of each other. A rendering filter is used to seperate HTML and r3f components and render them in the appropriate container.

Below is a quick rundown of changes we added/changed to get our 3D adventure started:

Fix/Circumvent SSR using next-transpile-modules

Three.js, Drei etc. don't play well with SSR so we needed a way to pre-transpile these libraries.
blitz.config.js

Reusable Canvas

Our goal here was to leverage a "reusable" Canvas ala react-three-next. All "3D" elements (hero, logo, etc. in our case) would render as children of this element. We also included some configurable niceties like r3f-perf, OrbitControls.
app/core/layouts/_canvas.tsx

DOM/HTML Component Container

Also similarly to react-three-next we used a wrapper for all non 3D or plain "dom" elements.
app/core/layouts/_dom.tsx

SplitApp

Then, we use this component either aggregate the 3D and non-3D components, if 3D components are present. Or, just output a standard non-canvas component wrapper.k
app/core/layouts/Layout.tsx#L29

Layout

As described earlier, this component is used to create separate arrays of r3f and HTML based on the presence of a "key". Using these arrays we determine whether or not to display the Canvas.
app/core/layouts/Layout.tsx

Index

Finally, we import our 3D component and disable SSR. Then, we use the Layout component from above and mark each 3D with a key (i.e. 'r3f', etc.) to let the render know we will be presenting a r3f component.
app/pages/index.tsx

The react-three-blitz starter is definitely a work-in-progress. In fact, we don't have all the coolness ported yet from react-three-next (i.e. transitions, webpack customization, etc.). Also, there in-progress r3f issue preventing us from sharing a canvas across routes to optimize navigation responsiveness.

Allow opting out of forceContextLoss() #1004

I'm working on a page where I would like to reuse/manage webgl contexts outside of the specific components that use Canvas. would it be possible to add a way to opt out of Canvas calling forceContextLoss() on unmount?

Nevertheless, we encourage you to give react-three-blitz a spin!

Open in Gitpod

-c0d3t3k

GitHub logo c0d3t3k / react-three-blitz

React Three Fiber experimental starter template powered by Blitz.js

Blitz.js

dev.to .Intro Video

Discord Shield

Open in Gitpod

react-three-blitz

Blitz.js experiment/starter influenced heavily by @onireanud et al react-three-next

Getting Started

Run your app in the development mode.

yarn
yarn dev

Open http://localhost:3000 with your browser to see the result.

Interesting Changes

List of delta's from the base Blitz.js generated app

react-three-blitz
β”œβ”€β”€ app/
β”‚Β Β  β”œβ”€β”€ core/
| Β  β”‚Β Β  └── components/ 
β”‚Β Β  β”‚Β Β  |   └── DarkMode.tsx
β”‚Β Β  β”‚Β Β  |   └── Logo.tsx
β”‚Β Β  β”‚Β Β  └── layouts/
β”‚Β Β  β”‚Β Β      └── _canvas.tsx
β”‚Β Β  β”‚Β Β      └── _dom.tsx
β”‚Β Β  β”‚Β Β      └── Layout.tsx
β”‚Β Β  β”œβ”€β”€ pages/
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ _app.tsx
β”‚Β Β  β”‚Β Β  └── index.tsx
β”‚Β Β  β”‚Β Β  └── hero.tsx
β”‚Β Β  β”œβ”€β”€ api/
β”‚Β Β  β”œβ”€β”€ auth/
β”‚Β Β  Β    β”œβ”€β”€ pages/
β”‚Β Β  Β   Β β”œβ”€β”€ login3d.tsx
β”‚Β Β  Β    └── signup3d.tsx
β”œβ”€β”€ blitz.config.js
β”œβ”€β”€ tsconfig.json

#shouldersofgiants shoutouts:




Discussion (0)