tremor
tremor copied to clipboard
Next.js 13 with app folder
I'm trying new app folder which is in beta now since Next.js 13.
But using the app folder, I have an error message that I don't have in pages folder.
I have pushed a minimal repos for testing purpose: https://github.com/srod/nextjs-13-tremor
git clone https://github.com/srod/nextjs-13-tremor.git
cd nextjs-13-tremor
npm install && npm run dev
Access example page: http://localhost:3000/example
error - (sc_server)/node_modules/@tremor/react/dist/cjs/index.js (6:41848) @ eval
error - TypeError: Super expression must either be null or a function
at eval (webpack-internal:///(sc_server)/./node_modules/@tremor/react/dist/cjs/index.js:1884:57)
at eval (webpack-internal:///(sc_server)/./node_modules/@tremor/react/dist/cjs/index.js:1892:6)
at eval (webpack-internal:///(sc_server)/./node_modules/@tremor/react/dist/cjs/index.js:1952:2)
at Object.(sc_server)/./node_modules/@tremor/react/dist/cjs/index.js (/Users/rodolphe/Downloads/nextjs-13-tremor/.next/server/app/example/page.js:251:1)
at __webpack_require__ (/Users/rodolphe/Downloads/nextjs-13-tremor/.next/server/webpack-runtime.js:33:42)
at eval (webpack-internal:///(sc_server)/./app/example/page.tsx:6:71)
at Object.(sc_server)/./app/example/page.tsx (/Users/rodolphe/Downloads/nextjs-13-tremor/.next/server/app/example/page.js:229:1)
at __webpack_require__ (/Users/rodolphe/Downloads/nextjs-13-tremor/.next/server/webpack-runtime.js:33:42)
at Object.page (webpack-internal:///(sc_server)/./node_modules/next/dist/build/webpack/loaders/next-app-loader.js?name=app%2Fexample%2Fpage&appPaths=%2Fexample%2Fpage&pagePath=private-next-app-dir%2Fexample%2Fpage.tsx&appDir=%2FUsers%2Frodolphe%2FDownloads%2Fnextjs-13-tremor%2Fapp&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&rootDir=%2FUsers%2Frodolphe%2FDownloads%2Fnextjs-13-tremor&isDev=true&tsconfigPath=tsconfig.json!:22:124)
at collectGenerateParams (/Users/rodolphe/Downloads/nextjs-13-tremor/node_modules/next/dist/build/utils.js:710:194) {
type: 'TypeError',
page: '/example'
}
null
It appears to be related with server side rendering.
Because it's working by adding 'use client'; at the top of app/example/page.tsx.
hi @srod, thanks for pointing this out & for your research! We did not have the time to deal with Next v13 yet unfortunately. We will try to deal with this as soon as possible though, thanks for the patience.
hi @srod,
When using components that are interactivity, in Next 13, I would suggest creating another file (a wrapper of the component that you want to display), which will be rendered only on the client. The default behavior of Next 13 is server-first, relying on RSC.
Because it's working by adding 'use client'; at the top of app/example/page.tsx.
Adding "use client" at the top of page.tsx will make the entire page be client rendered.
How to make it work
Let's say you want to add an Area Chart to any of your pages.
Let's create a component called AreaChartComponent.tsx (this is only a wrapper, where we specify that it needs to be client rendered).
"use client";
import { Card, Title, AreaChart } from "@tremor/react";
const chartdata = [
{
date: "Jan 22",
SemiAnalysis: 2890,
"The Pragmatic Engineer": 2338,
},
{
date: "Feb 22",
SemiAnalysis: 2756,
"The Pragmatic Engineer": 2103,
},
{
date: "Mar 22",
SemiAnalysis: 3322,
"The Pragmatic Engineer": 2194,
},
{
date: "Apr 22",
SemiAnalysis: 3470,
"The Pragmatic Engineer": 2108,
},
{
date: "May 22",
SemiAnalysis: 3475,
"The Pragmatic Engineer": 1812,
},
{
date: "Jun 22",
SemiAnalysis: 3129,
"The Pragmatic Engineer": 1726,
},
];
const dataFormatter = (number: number) => {
return "$ " + Intl.NumberFormat("us").format(number).toString();
};
export default function AreaChartComponent() {
return (
<Card>
<Title>Newsletter revenue over time (USD)</Title>
<AreaChart
data={chartdata}
categories={["SemiAnalysis", "The Pragmatic Engineer"]}
dataKey="date"
height="h-72"
colors={["indigo", "cyan"]}
valueFormatter={dataFormatter}
marginTop="mt-4"
/>
</Card>
);
}
Now, in your app/example/page.tsx, let's remove the "use client", and just import our wrapper component.
/* other imports */
import Component from "./component";
export default function Page() {
return (
<div>
{/* other stuff */}
<Component />
</div>
);
}
@mitrotasios About the error message:
error - TypeError: Super expression must either be null or a function
The issue might be related to circular dependencies from d3-interpolate + incorrect usage of client components.
(!) Circular dependencies
node_modules/d3-interpolate/src/value.js -> node_modules/d3-interpolate/src/array.js -> node_modules/d3-interpolate/src/value.js
node_modules/d3-interpolate/src/value.js -> node_modules/d3-interpolate/src/object.js -> node_modules/d3-interpolate/src/value.js
Additionally, I think that the labels could be removed.
Thanks a lot @mariusflorescu! Indeed, I think for now the best way to use the app directory from Next 13 along with tremor is to wrap the tremor components into a client component by including the "use client"; directive.
Also feel free to check out the Next.js docs on how to integrate third-party packages for more info.
Tremor works in RSC if you add it in next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
appDir: true,
serverComponentsExternalPackages: ["@tremor/react"],
},
};
module.exports = nextConfig;
See https://twitter.com/chronark_/status/1612522989521891328
Thanks @chronark, will also add this to the documentation!
hi @mitrotasios , I can help to create a PR for the documentation (or at least readme) if it's not yet created. I also got the error and had no idea to fix it before I found the solution in twitter.
That would be awesome, thanks @tegarimansyah! Sorry, totally forgot about that 🤦🏼♂️
Hi @mitrotasios , please review the PR here. It's a small changes in readme file. I think you also need to update the docs site.
Thanks for the opportunity to contribute to this awesome project
thanks for contributing! 🙂
Hit into this issue. Specifying ``` serverComponentsExternalPackages: ["@tremor/react"],
as mentioned by @chronark did not help.
I still have to use it in a client component ('use client' directive) to make it work.
If I do not use the "use client" option, I run into the issue of
Cannot set properties of undefined (setting 'props')
/Users/shriharip/nextprojects/proj/node_modules/.pnpm/@[email protected]_biqbaboplfbrettd7655fr4n2y/node_modules/@tremor/react/dist/cjs/index.js (249:457609)
type node_modules/.pnpm/[email protected]_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (1379:17) attemptResolveElement node_modules/.pnpm/[email protected]_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (1941:20) resolveModelToJSON node_modules/.pnpm/[email protected]_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (1204:13)
stringify node_modules/.pnpm/[email protected]_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (197:13) processModelChunk node_modules/.pnpm/[email protected]_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (2208:25) retryTask node_modules/.pnpm/[email protected]_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (2255:6) performWork node_modules/.pnpm/[email protected]_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (1475:13) callback node_modules/.pnpm/[email protected]_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (60:2) scheduleWork node_modules/.pnpm/[email protected]_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (1474:4) pingTask node_modules/.pnpm/[email protected]_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (1488:13)
Yeah that's still required for some components.
the whole use client thing is a bit tricky cause it's not as simple as putting "use client" in the component file in tremor, because other frameworks or react by itself can choke on that :/
you can do this:
// app/components/tremor.tsx
"use client"
export * from "@tremor/react"
and then import all your components from this file
Would be nice to work on server components too (at least button or simple component).