@leanjs/next
v0.8.12
Published
Lean micro-app tools for Nextjs
Downloads
64
Maintainers
Readme
@leanjs/next
Installation
If your Nextjs app is in a monorepo (recommended) execute the following command at the root of your repository:
yarn add -W @leanjs/next @leanjs/react @leanjs/core \
next@13 react@18 react-dom@18
then in the package.json
of your Nextjs app add the following peerDependencies
:
"peerDependencies": {
"@leanjs/core": "*",
"@leanjs/next": "*",
"@leanjs/react": "*",
"next": "*",
"react": "*",
"react-dom": "*"
}
If your Nextjs app is not in a monorepo, then run the following command instead of the above:
yarn add @leanjs/next @leanjs/react @leanjs/core \
next@13 react@18 react-dom@18
:::info
The LeanJS integration for Nextjs only supports React 18 and Nextjs 13.
:::
Basic usage
HostProvider
You have to add a HostProvider
at the root of your component tree in pages/_app.tsx
. Heads up! HostProvider
is not exported from @leanjs/next
. Learn more about the HostProvider
.
Example:
import type { AppProps } from "next/app";
import React from "react";
// react runtime package created within your org
import { HostProvider, createRuntime } from "@my-org/react-runtime";
const runtime = createRuntime({ context: { appName: "AppExample" } });
const App = ({ Component, pageProps }: AppProps) => (
<HostProvider runtime={runtime}>
<Component {...pageProps} />
</HostProvider>
);
export default App;
:::info
Read @leanjs/core if you have not already created your own createRuntime
function
:::
Components
The examples in this section are based on the following project structure:
my-monorepo/
├─ apps/
│ ├─ nextjs-host/
│ │ ├─ next.config.js
├─ composable-apps/
│ ├─ react-app-1/
│ │ ├─ package.json
│ │ ├─ src/
│ │ │ ├─ ReactApp1.tsx
│ │ │ ├─ index.ts
├─ package.json
Host
It hosts a composable app in a Next host.
app
- required prop
The app
prop expects a GetComposableApp
type. You can import
a GetComposableApp
from any export default createApp()
function, for instance:
// my-monorepo/composable-apps/react-app-1/src/index.ts
// for either React 16 or React 17 import from "@leanjs/react/17"
import { createApp } from "@leanjs/react/18";
import { ReactApp1 } from "./ReactApp1";
export default createApp(ReactApp1);
:::info
In this example the composable app is a React app. However, the Nextjs <Host>
component can host any composable app, e.g. Vue.
:::
then pass it to the Host
component in a Next.js app:
// my-monorepo/apps/nextjs-host/pages/index.tsx
import { Host } from "@leanjs/next";
// this composable app is bundled and deployed along with the Nextjs app
import ReactApp1 from "@my-org/react-app-1";
const Home = () => (
<>
<h1>Nextjs Host</h1>
<Host app={ReactApp1} />
</>
);
export default Home;
You can also pass a function to the Host
component that returns a dynamic import to lazy load a composable app:
// my-monorepo/apps/nextjs-host/pages/index.tsx
import React, { Suspense } from "react";
import { Host, ErrorBoundary } from "@leanjs/next";
const Home = () => (
<>
<h1>Nextjs Host</h1>
{/* The network can fail.
Add an ErrorBoundary if you are hosting an app using a dynamic import */}
<ErrorBoundary>
<Suspense fallback={<p>Loading...</p>}>
<Host
app={() => {
// this composable app is bundled in a separate chunk
// but it's still built and deployed along with the Nextjs app
return import("@my-org/react-app-1");
}}
/>
</Suspense>
</ErrorBoundary>
</>
);
export default Home;
Alternatively, you can pass an object to the app
prop with a packageName
key which value is the field name
in the package.json of the composable app that you want to host. In this case, the Host
component will try to fetch the mount
function from the remote origin
specified in <HostProvider origin=" 👉 HERE 👈 " runtime={runtime}>
(see origin prop to know more). For example:
// my-monorepo/apps/nextjs-host/pages/index.tsx
import React, { Suspense } from "react";
import { Host, ErrorBoundary } from "@leanjs/next";
const Home = () => (
<>
<h1>Nextjs Host</h1>
{/* The network can fail.
Add an ErrorBoundary if you are hosting a remote app */}
<ErrorBoundary>
<Suspense fallback={<p>Loading...</p>}>
{/* in this case, the composable app is neither built nor deployed
along with the Next.js host */}
<Host app={{ packageName: "@my-org/react-app-1" }} />
</Suspense>
</ErrorBoundary>
</>
);
export default Home;
:::caution
Fetching from a remote origin
only works with Webpack v5 because this feature uses Module Federation under the hood. You need to add a HostWebpackPlugin to your next.config.js
to enable this feature. If this feature is enabled you need to build and deploy your composable apps independently. See @leanjs/aws to deploy your composable apps to AWS.
:::
className
- optional prop
CSS class added to the root DOM element where the app
prop is mounted.
// my-monorepo/apps/react-host/src/index.ts
import React from "react";
import { Host } from "@leanjs/next";
import ReactApp1 from "@my-org/react-app-1";
const Home = () => (
<>
<h1>Next Host</h1>
<Host className="some-css-class" app={ReactApp1} />
</>
);
export default Home;