added handy nextjs-plasmic-bknd functions

This commit is contained in:
dswbx
2025-01-23 10:59:33 +01:00
parent f64e5dac03
commit 2265451d4b
3 changed files with 151 additions and 8 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "@bknd/plasmic", "name": "@bknd/plasmic",
"version": "0.5.0", "version": "0.5.1",
"type": "module", "type": "module",
"sideEffects": false, "sideEffects": false,
"scripts": { "scripts": {
@@ -30,9 +30,13 @@
"@plasmicapp/host": ">=1.0.0", "@plasmicapp/host": ">=1.0.0",
"@plasmicapp/loader-react": ">=1.0.0" "@plasmicapp/loader-react": ">=1.0.0"
}, },
"optionalDependencies": {
"@plasmicapp/loader-nextjs": "^1.0.0"
},
"tsup": { "tsup": {
"entry": [ "entry": [
"src/index.ts" "src/index.ts",
"src/nextjs/index.tsx"
], ],
"minify": true, "minify": true,
"clean": true, "clean": true,
@@ -42,7 +46,11 @@
"@plasmicapp/host", "@plasmicapp/host",
"@plasmicapp/query", "@plasmicapp/query",
"@plasmicapp/loader-react", "@plasmicapp/loader-react",
"swr" "@plasmicapp/loader-nextjs",
"swr",
"next",
"next/error",
"next/router"
], ],
"format": [ "format": [
"esm" "esm"
@@ -54,9 +62,19 @@
"sourceMap": true, "sourceMap": true,
"outDir": "dist" "outDir": "dist"
}, },
"types": "dist/index.d.ts", "types": "./dist/index.d.ts",
"module": "dist/index.js", "module": "./dist/index.js",
"main": "dist/index.js", "main": "./dist/index.js",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
},
"./nextjs": {
"types": "./dist/nextjs/index.d.ts",
"import": "./dist/nextjs/index.js"
}
},
"files": [ "files": [
"dist", "dist",
"README.md", "README.md",

View File

@@ -6,7 +6,7 @@ import {
} from "@plasmicapp/host"; } from "@plasmicapp/host";
import { usePlasmicQueryData } from "@plasmicapp/loader-react"; import { usePlasmicQueryData } from "@plasmicapp/loader-react";
import { useApi, useEntityQuery } from "bknd/client"; import { useApi, useEntityQuery } from "bknd/client";
import type { RepoQuery } from "bknd/data"; import type { RepoQueryIn } from "bknd/data";
// biome-ignore lint/style/useImportType: <explanation> // biome-ignore lint/style/useImportType: <explanation>
import React from "react"; import React from "react";
import { usePlasmicBkndContext } from "../../contexts/BkndContext"; import { usePlasmicBkndContext } from "../../contexts/BkndContext";
@@ -171,7 +171,7 @@ type ModeProps = {
error?: React.ReactNode; error?: React.ReactNode;
empty?: React.ReactNode; empty?: React.ReactNode;
entityId?: number; entityId?: number;
query?: Partial<RepoQuery>; query?: RepoQueryIn;
}; };
const ModeFetch = ({ const ModeFetch = ({

View File

@@ -0,0 +1,125 @@
import {
type ComponentRenderData,
type NextJsPlasmicComponentLoader,
PlasmicComponent,
PlasmicRootProvider,
extractPlasmicQueryData
} from "@plasmicapp/loader-nextjs";
import type { GetStaticPaths, GetStaticProps, GetStaticPropsContext } from "next";
import NextjsError from "next/error";
import { useRouter } from "next/router";
import React from "react";
type TPlasmic = NextJsPlasmicComponentLoader;
export type TGetStaticPropsOptions = {
baseUrl?: string;
revalidate?: number | boolean;
};
export function plasmicNextjsStatic(PLASMIC: TPlasmic, opts?: TGetStaticPropsOptions) {
return {
getStaticPaths: getStaticPaths(PLASMIC),
getStaticProps: getStaticProps(PLASMIC, opts),
CatchallPage: CatchallPage(PLASMIC)
};
}
export function getStaticPaths(PLASMIC: TPlasmic): GetStaticPaths {
return async () => {
const pages = await PLASMIC.fetchPages();
return {
paths: pages.map((page) => ({
params: { catchall: page.path.substring(1).split("/") }
})),
fallback: "blocking"
};
};
}
export function getStaticProps(PLASMIC: TPlasmic, opts?: TGetStaticPropsOptions): GetStaticProps {
return async (context: GetStaticPropsContext) => {
const baseUrl = opts?.baseUrl ?? process.env.BASE_URL!;
let { catchall } = context.params ?? {};
if (catchall && Array.isArray(catchall) && catchall[0] === "index") {
console.log("setting catch all to undefined");
catchall = undefined;
}
const globalContextsProps = {
bkndContextProps: {
baseUrl
}
};
// Convert the catchall param into a path string
const plasmicPath =
typeof catchall === "string"
? catchall
: catchall !== null && Array.isArray(catchall)
? `/${catchall.join("/")}`
: "/";
const plasmicData = await PLASMIC.maybeFetchComponentData(plasmicPath);
if (!plasmicData) {
// This is some non-Plasmic catch-all page
return {
props: {}
};
}
// This is a path that Plasmic knows about.
const pageMeta = plasmicData.entryCompMetas[0];
// Cache the necessary data fetched for the page.
const queryCache = await extractPlasmicQueryData(
<PlasmicRootProvider
loader={PLASMIC}
prefetchedData={plasmicData}
pageRoute={pageMeta.path}
pageParams={pageMeta.params}
globalContextsProps={globalContextsProps}
>
<PlasmicComponent component={pageMeta.displayName} />
</PlasmicRootProvider>
);
const props = { plasmicData, queryCache, globalContextsProps };
// Pass the data in as props.
return {
props,
// Using incremental static regeneration, will invalidate this page
// after 300s (no deploy webhooks needed)
revalidate: opts?.revalidate ?? 300
};
};
}
export function CatchallPage(PLASMIC: TPlasmic) {
return (props: {
plasmicData?: ComponentRenderData;
queryCache?: Record<string, any>;
globalContextsProps?: any;
}) => {
const { plasmicData, queryCache, globalContextsProps } = props;
const router = useRouter();
if (!plasmicData || plasmicData.entryCompMetas.length === 0) {
return <NextjsError statusCode={404} />;
}
const pageMeta = plasmicData.entryCompMetas[0];
return (
<PlasmicRootProvider
loader={PLASMIC}
prefetchedData={plasmicData}
prefetchedQueryData={queryCache}
pageRoute={pageMeta.path}
pageParams={pageMeta.params}
pageQuery={router.query}
globalContextsProps={globalContextsProps}
>
<PlasmicComponent component={pageMeta.displayName} />
</PlasmicRootProvider>
);
};
}