create-plasmic-app 0.0.134 → 0.0.136

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/cpa-out/nextjs-app-loader-js/app/[[...catchall]]/page.jsx +80 -0
  2. package/cpa-out/nextjs-app-loader-js/app/layout.js +28 -0
  3. package/cpa-out/nextjs-app-loader-js/app/plasmic-host/page.jsx +6 -0
  4. package/cpa-out/nextjs-app-loader-js/plasmic-init-client.jsx +65 -0
  5. package/cpa-out/nextjs-app-loader-js/plasmic-init.js +5 -10
  6. package/cpa-out/nextjs-app-loader-ts/app/[[...catchall]]/page.tsx +85 -0
  7. package/cpa-out/nextjs-app-loader-ts/app/layout.tsx +33 -0
  8. package/cpa-out/nextjs-app-loader-ts/app/plasmic-host/page.tsx +6 -0
  9. package/cpa-out/nextjs-app-loader-ts/plasmic-init-client.tsx +65 -0
  10. package/cpa-out/nextjs-app-loader-ts/plasmic-init.ts +5 -10
  11. package/cpa-out/nextjs-app-loader-ts/tsconfig.json +6 -1
  12. package/dist/index.js +0 -2
  13. package/dist/nextjs/templates/app-loader/catchall-page.js +63 -38
  14. package/dist/nextjs/templates/app-loader/plasmic-init-client.js +1 -1
  15. package/dist/nextjs/templates/app-loader/plasmic-init.js +4 -0
  16. package/dist/react/react.js +1 -1
  17. package/package.json +2 -2
  18. package/src/index.ts +0 -2
  19. package/src/nextjs/templates/app-loader/catchall-page.ts +80 -43
  20. package/src/nextjs/templates/app-loader/plasmic-init-client.ts +1 -1
  21. package/src/nextjs/templates/app-loader/plasmic-init.ts +4 -0
  22. package/src/react/react.ts +1 -1
  23. package/cpa-out/nextjs-app-loader-js/pages/[[...catchall]].jsx +0 -68
  24. package/cpa-out/nextjs-app-loader-js/pages/api/hello.js +0 -5
  25. package/cpa-out/nextjs-app-loader-js/pages/plasmic-host.jsx +0 -7
  26. package/cpa-out/nextjs-app-loader-ts/pages/[[...catchall]].tsx +0 -72
  27. package/cpa-out/nextjs-app-loader-ts/pages/api/hello.ts +0 -13
  28. package/cpa-out/nextjs-app-loader-ts/pages/plasmic-host.tsx +0 -7
@@ -0,0 +1,80 @@
1
+ import { PLASMIC } from "@/plasmic-init";
2
+ import { ClientPlasmicRootProvider } from "@/plasmic-init-client";
3
+ import { PlasmicComponent } from "@plasmicapp/loader-nextjs";
4
+ import { notFound } from "next/navigation";
5
+
6
+ // Use revalidate if you want incremental static regeneration
7
+ export const revalidate = 60;
8
+
9
+ export async function generateStaticParams() {
10
+ const pageModules = await PLASMIC.fetchPages();
11
+ return pageModules.map((mod) => {
12
+ const catchall =
13
+ mod.path === "/" ? undefined : mod.path.substring(1).split("/");
14
+ return {
15
+ catchall,
16
+ };
17
+ });
18
+ }
19
+
20
+ export async function generateMetadata(
21
+ { params },
22
+ parent
23
+ ) {
24
+ const { componentData } = await getPlasmicData(params);
25
+
26
+ if (!componentData) {
27
+ return parent;
28
+ }
29
+ const pageMeta = componentData.entryCompMetas[0];
30
+ const metadata = await PLASMIC.unstable__generateMetadata(componentData, {
31
+ params: pageMeta.params ?? {},
32
+ query: {},
33
+ });
34
+
35
+ return { ...(await parent), ...metadata };
36
+ }
37
+
38
+ export default async function PlasmicLoaderPage({
39
+ params,
40
+ }) {
41
+ const { pagePath, componentData } = await getPlasmicData(params);
42
+
43
+ if (!componentData) {
44
+ notFound();
45
+ }
46
+ const pageMeta = componentData.entryCompMetas[0];
47
+ const prefetchedQueryData = await PLASMIC.unstable__getServerQueriesData(
48
+ componentData,
49
+ {
50
+ pagePath,
51
+ params: pageMeta.params,
52
+ query: {},
53
+ }
54
+ );
55
+
56
+ return (
57
+ <ClientPlasmicRootProvider
58
+ prefetchedData={componentData}
59
+ prefetchedQueryData={prefetchedQueryData}
60
+ pageParams={pageMeta.params}
61
+ pageRoute={pageMeta.path}
62
+ >
63
+ <PlasmicComponent component={pageMeta.displayName} />
64
+ </ClientPlasmicRootProvider>
65
+ );
66
+ }
67
+
68
+ async function getPlasmicData(
69
+ params
70
+ ) {
71
+ const catchall = (await params).catchall;
72
+ const pagePath = catchall ? `/${catchall.join("/")}` : "/";
73
+
74
+ const componentData = await PLASMIC.maybeFetchComponentData(pagePath);
75
+
76
+ if (!componentData || componentData.entryCompMetas.length === 0) {
77
+ return { pagePath };
78
+ }
79
+ return { pagePath, componentData };
80
+ }
@@ -0,0 +1,28 @@
1
+ import localFont from "next/font/local";
2
+ import "./globals.css";
3
+
4
+ const geistSans = localFont({
5
+ src: "./fonts/GeistVF.woff",
6
+ variable: "--font-geist-sans",
7
+ weight: "100 900",
8
+ });
9
+ const geistMono = localFont({
10
+ src: "./fonts/GeistMonoVF.woff",
11
+ variable: "--font-geist-mono",
12
+ weight: "100 900",
13
+ });
14
+
15
+ export const metadata = {
16
+ title: "Create Next App",
17
+ description: "Generated by create next app",
18
+ };
19
+
20
+ export default function RootLayout({ children }) {
21
+ return (
22
+ <html lang="en">
23
+ <body className={`${geistSans.variable} ${geistMono.variable}`}>
24
+ {children}
25
+ </body>
26
+ </html>
27
+ );
28
+ }
@@ -0,0 +1,6 @@
1
+ import { PlasmicCanvasHost } from "@plasmicapp/loader-nextjs";
2
+ import "@/plasmic-init-client";
3
+
4
+ export default function PlasmicHost() {
5
+ return <PlasmicCanvasHost />;
6
+ }
@@ -0,0 +1,65 @@
1
+ "use client";
2
+
3
+ import { PlasmicRootProvider } from "@plasmicapp/loader-nextjs";
4
+ import { PLASMIC } from "@/plasmic-init";
5
+
6
+ // You can register any code components that you want to use here; see
7
+ // https://docs.plasmic.app/learn/code-components-ref/
8
+ // And configure your Plasmic project to use the host url pointing at
9
+ // the /plasmic-host page of your nextjs app (for example,
10
+ // http://localhost:3000/plasmic-host). See
11
+ // https://docs.plasmic.app/learn/app-hosting/#set-a-plasmic-project-to-use-your-app-host
12
+
13
+ // PLASMIC.registerComponent(...);
14
+
15
+ /**
16
+ * ClientPlasmicRootProvider is a Client Component that passes in the loader for you.
17
+ *
18
+ * Why? Props passed from Server to Client Components must be serializable.
19
+ * https://nextjs.org/docs/app/getting-started/server-and-client-components#passing-data-from-server-to-client-components
20
+ * However, PlasmicRootProvider requires a loader, but the loader is NOT serializable.
21
+ *
22
+ * In a Server Component like app/<your-path>/path.tsx, rendering the following would not work:
23
+ *
24
+ * ```tsx
25
+ * import { PLASMIC } from "@/plasmic-init";
26
+ * import { PlasmicRootProvider } from "plasmicapp/loader-nextjs";
27
+ * export default function MyPage() {
28
+ * const prefetchedData = await PLASMIC.fetchComponentData("YourPage");
29
+ * return (
30
+ * <PlasmicRootProvider
31
+ * loader={PLASMIC} // ERROR: loader is not serializable
32
+ * prefetchedData={prefetchedData}
33
+ * >
34
+ * {yourContent()}
35
+ * </PlasmicRootProvider>;
36
+ * );
37
+ * }
38
+ * ```
39
+ *
40
+ * Therefore, we define ClientPlasmicRootProvider as a Client Component (this file is marked "use client").
41
+ * ClientPlasmicRootProvider wraps the PlasmicRootProvider and passes in the loader for you,
42
+ * while allowing your Server Component to pass in prefetched data and other serializable props:
43
+ *
44
+ * ```tsx
45
+ * import { PLASMIC } from "@/plasmic-init";
46
+ * import { ClientPlasmicRootProvider } from "@/plasmic-init-client"; // changed
47
+ * export default function MyPage() {
48
+ * const prefetchedData = await PLASMIC.fetchComponentData("YourPage");
49
+ * return (
50
+ * <ClientPlasmicRootProvider // don't pass in loader
51
+ * prefetchedData={prefetchedData}
52
+ * >
53
+ * {yourContent()}
54
+ * </ClientPlasmicRootProvider>;
55
+ * );
56
+ * }
57
+ * ```
58
+ */
59
+ export function ClientPlasmicRootProvider(
60
+ props
61
+ ) {
62
+ return (
63
+ <PlasmicRootProvider loader={PLASMIC} {...props}></PlasmicRootProvider>
64
+ );
65
+ }
@@ -1,4 +1,5 @@
1
- import { initPlasmicLoader } from "@plasmicapp/loader-nextjs";
1
+ import { initPlasmicLoader } from "@plasmicapp/loader-nextjs/react-server-conditional";
2
+ import * as NextNavigation from "next/navigation";
2
3
 
3
4
  export const PLASMIC = initPlasmicLoader({
4
5
  projects: [
@@ -13,13 +14,7 @@ export const PLASMIC = initPlasmicLoader({
13
14
  // project, allowing you to see your designs without publishing. Please
14
15
  // only use this for development, as this is significantly slower.
15
16
  preview: false,
16
- });
17
-
18
- // You can register any code components that you want to use here; see
19
- // https://docs.plasmic.app/learn/code-components-ref/
20
- // And configure your Plasmic project to use the host url pointing at
21
- // the /plasmic-host page of your nextjs app (for example,
22
- // http://localhost:3000/plasmic-host). See
23
- // https://docs.plasmic.app/learn/app-hosting/#set-a-plasmic-project-to-use-your-app-host
24
17
 
25
- // PLASMIC.registerComponent(...);
18
+ // Needed for Next.js app router support.
19
+ nextNavigation: NextNavigation,
20
+ });
@@ -0,0 +1,85 @@
1
+ import { PLASMIC } from "@/plasmic-init";
2
+ import { ClientPlasmicRootProvider } from "@/plasmic-init-client";
3
+ import { ComponentRenderData,PlasmicComponent } from "@plasmicapp/loader-nextjs";
4
+ import { Metadata, ResolvingMetadata } from "next";
5
+ import { notFound } from "next/navigation";
6
+
7
+ // Use revalidate if you want incremental static regeneration
8
+ export const revalidate = 60;
9
+ interface Params {
10
+ catchall: string[] | undefined;
11
+ }
12
+ export async function generateStaticParams(): Promise<Params[]> {
13
+ const pageModules = await PLASMIC.fetchPages();
14
+ return pageModules.map((mod) => {
15
+ const catchall =
16
+ mod.path === "/" ? undefined : mod.path.substring(1).split("/");
17
+ return {
18
+ catchall,
19
+ };
20
+ });
21
+ }
22
+ interface LoaderPageProps {
23
+ params: Promise<Params>;
24
+ }
25
+ export async function generateMetadata(
26
+ { params }: LoaderPageProps,
27
+ parent: ResolvingMetadata
28
+ ): Promise<Metadata> {
29
+ const { componentData } = await getPlasmicData(params);
30
+
31
+ if (!componentData) {
32
+ return parent as Promise<Metadata>;
33
+ }
34
+ const pageMeta = componentData.entryCompMetas[0];
35
+ const metadata = await PLASMIC.unstable__generateMetadata(componentData, {
36
+ params: pageMeta.params ?? {},
37
+ query: {},
38
+ });
39
+
40
+ return { ...(await parent), ...metadata };
41
+ }
42
+
43
+ export default async function PlasmicLoaderPage({
44
+ params,
45
+ }: LoaderPageProps) {
46
+ const { pagePath, componentData } = await getPlasmicData(params);
47
+
48
+ if (!componentData) {
49
+ notFound();
50
+ }
51
+ const pageMeta = componentData.entryCompMetas[0];
52
+ const prefetchedQueryData = await PLASMIC.unstable__getServerQueriesData(
53
+ componentData,
54
+ {
55
+ pagePath,
56
+ params: pageMeta.params,
57
+ query: {},
58
+ }
59
+ );
60
+
61
+ return (
62
+ <ClientPlasmicRootProvider
63
+ prefetchedData={componentData}
64
+ prefetchedQueryData={prefetchedQueryData}
65
+ pageParams={pageMeta.params}
66
+ pageRoute={pageMeta.path}
67
+ >
68
+ <PlasmicComponent component={pageMeta.displayName} />
69
+ </ClientPlasmicRootProvider>
70
+ );
71
+ }
72
+
73
+ async function getPlasmicData(
74
+ params: Promise<Params>
75
+ ): Promise<{ pagePath: string; componentData?: ComponentRenderData }> {
76
+ const catchall = (await params).catchall;
77
+ const pagePath = catchall ? `/${catchall.join("/")}` : "/";
78
+
79
+ const componentData = await PLASMIC.maybeFetchComponentData(pagePath);
80
+
81
+ if (!componentData || componentData.entryCompMetas.length === 0) {
82
+ return { pagePath };
83
+ }
84
+ return { pagePath, componentData };
85
+ }
@@ -0,0 +1,33 @@
1
+ import type { Metadata } from "next";
2
+ import localFont from "next/font/local";
3
+ import "./globals.css";
4
+
5
+ const geistSans = localFont({
6
+ src: "./fonts/GeistVF.woff",
7
+ variable: "--font-geist-sans",
8
+ weight: "100 900",
9
+ });
10
+ const geistMono = localFont({
11
+ src: "./fonts/GeistMonoVF.woff",
12
+ variable: "--font-geist-mono",
13
+ weight: "100 900",
14
+ });
15
+
16
+ export const metadata: Metadata = {
17
+ title: "Create Next App",
18
+ description: "Generated by create next app",
19
+ };
20
+
21
+ export default function RootLayout({
22
+ children,
23
+ }: Readonly<{
24
+ children: React.ReactNode;
25
+ }>) {
26
+ return (
27
+ <html lang="en">
28
+ <body className={`${geistSans.variable} ${geistMono.variable}`}>
29
+ {children}
30
+ </body>
31
+ </html>
32
+ );
33
+ }
@@ -0,0 +1,6 @@
1
+ import { PlasmicCanvasHost } from "@plasmicapp/loader-nextjs";
2
+ import "@/plasmic-init-client";
3
+
4
+ export default function PlasmicHost() {
5
+ return <PlasmicCanvasHost />;
6
+ }
@@ -0,0 +1,65 @@
1
+ "use client";
2
+
3
+ import { PlasmicRootProvider } from "@plasmicapp/loader-nextjs";
4
+ import { PLASMIC } from "@/plasmic-init";
5
+
6
+ // You can register any code components that you want to use here; see
7
+ // https://docs.plasmic.app/learn/code-components-ref/
8
+ // And configure your Plasmic project to use the host url pointing at
9
+ // the /plasmic-host page of your nextjs app (for example,
10
+ // http://localhost:3000/plasmic-host). See
11
+ // https://docs.plasmic.app/learn/app-hosting/#set-a-plasmic-project-to-use-your-app-host
12
+
13
+ // PLASMIC.registerComponent(...);
14
+
15
+ /**
16
+ * ClientPlasmicRootProvider is a Client Component that passes in the loader for you.
17
+ *
18
+ * Why? Props passed from Server to Client Components must be serializable.
19
+ * https://nextjs.org/docs/app/getting-started/server-and-client-components#passing-data-from-server-to-client-components
20
+ * However, PlasmicRootProvider requires a loader, but the loader is NOT serializable.
21
+ *
22
+ * In a Server Component like app/<your-path>/path.tsx, rendering the following would not work:
23
+ *
24
+ * ```tsx
25
+ * import { PLASMIC } from "@/plasmic-init";
26
+ * import { PlasmicRootProvider } from "plasmicapp/loader-nextjs";
27
+ * export default function MyPage() {
28
+ * const prefetchedData = await PLASMIC.fetchComponentData("YourPage");
29
+ * return (
30
+ * <PlasmicRootProvider
31
+ * loader={PLASMIC} // ERROR: loader is not serializable
32
+ * prefetchedData={prefetchedData}
33
+ * >
34
+ * {yourContent()}
35
+ * </PlasmicRootProvider>;
36
+ * );
37
+ * }
38
+ * ```
39
+ *
40
+ * Therefore, we define ClientPlasmicRootProvider as a Client Component (this file is marked "use client").
41
+ * ClientPlasmicRootProvider wraps the PlasmicRootProvider and passes in the loader for you,
42
+ * while allowing your Server Component to pass in prefetched data and other serializable props:
43
+ *
44
+ * ```tsx
45
+ * import { PLASMIC } from "@/plasmic-init";
46
+ * import { ClientPlasmicRootProvider } from "@/plasmic-init-client"; // changed
47
+ * export default function MyPage() {
48
+ * const prefetchedData = await PLASMIC.fetchComponentData("YourPage");
49
+ * return (
50
+ * <ClientPlasmicRootProvider // don't pass in loader
51
+ * prefetchedData={prefetchedData}
52
+ * >
53
+ * {yourContent()}
54
+ * </ClientPlasmicRootProvider>;
55
+ * );
56
+ * }
57
+ * ```
58
+ */
59
+ export function ClientPlasmicRootProvider(
60
+ props: Omit<React.ComponentProps<typeof PlasmicRootProvider>, "loader">
61
+ ) {
62
+ return (
63
+ <PlasmicRootProvider loader={PLASMIC} {...props}></PlasmicRootProvider>
64
+ );
65
+ }
@@ -1,4 +1,5 @@
1
- import { initPlasmicLoader } from "@plasmicapp/loader-nextjs";
1
+ import { initPlasmicLoader } from "@plasmicapp/loader-nextjs/react-server-conditional";
2
+ import * as NextNavigation from "next/navigation";
2
3
 
3
4
  export const PLASMIC = initPlasmicLoader({
4
5
  projects: [
@@ -13,13 +14,7 @@ export const PLASMIC = initPlasmicLoader({
13
14
  // project, allowing you to see your designs without publishing. Please
14
15
  // only use this for development, as this is significantly slower.
15
16
  preview: false,
16
- });
17
-
18
- // You can register any code components that you want to use here; see
19
- // https://docs.plasmic.app/learn/code-components-ref/
20
- // And configure your Plasmic project to use the host url pointing at
21
- // the /plasmic-host page of your nextjs app (for example,
22
- // http://localhost:3000/plasmic-host). See
23
- // https://docs.plasmic.app/learn/app-hosting/#set-a-plasmic-project-to-use-your-app-host
24
17
 
25
- // PLASMIC.registerComponent(...);
18
+ // Needed for Next.js app router support.
19
+ nextNavigation: NextNavigation,
20
+ });
@@ -12,10 +12,15 @@
12
12
  "isolatedModules": true,
13
13
  "jsx": "preserve",
14
14
  "incremental": true,
15
+ "plugins": [
16
+ {
17
+ "name": "next"
18
+ }
19
+ ],
15
20
  "paths": {
16
21
  "@/*": ["./*"]
17
22
  }
18
23
  },
19
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
24
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
20
25
  "exclude": ["node_modules"]
21
26
  }
package/dist/index.js CHANGED
@@ -251,8 +251,6 @@ function run() {
251
251
  };
252
252
  }
253
253
  }
254
- // Get the projectId
255
- console.log();
256
254
  const projectInput = yield maybePrompt({
257
255
  name: "projectId",
258
256
  message: `If you don't have a project yet, create one by going to https://studio.plasmic.app/starters/blank
@@ -3,65 +3,90 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.makeCatchallPage_app_loader = void 0;
4
4
  const file_utils_1 = require("../../../utils/file-utils");
5
5
  function makeCatchallPage_app_loader(jsOrTs) {
6
- return `import { PlasmicComponent } from "@plasmicapp/loader-nextjs";
7
- import { notFound } from "next/navigation";
8
- import { PLASMIC } from "@/plasmic-init";
6
+ return `import { PLASMIC } from "@/plasmic-init";
9
7
  import { ClientPlasmicRootProvider } from "@/plasmic-init-client";
8
+ import { ${(0, file_utils_1.ifTs)(jsOrTs, `ComponentRenderData,`)}PlasmicComponent } from "@plasmicapp/loader-nextjs";${(0, file_utils_1.ifTs)(jsOrTs, `
9
+ import { Metadata, ResolvingMetadata } from "next";`)}
10
+ import { notFound } from "next/navigation";
10
11
 
11
12
  // Use revalidate if you want incremental static regeneration
12
13
  export const revalidate = 60;
14
+ ${(0, file_utils_1.ifTs)(jsOrTs, `interface Params {
15
+ catchall: string[] | undefined;
16
+ }`)}
17
+ export async function generateStaticParams()${(0, file_utils_1.ifTs)(jsOrTs, ": Promise<Params[]>")} {
18
+ const pageModules = await PLASMIC.fetchPages();
19
+ return pageModules.map((mod) => {
20
+ const catchall =
21
+ mod.path === "/" ? undefined : mod.path.substring(1).split("/");
22
+ return {
23
+ catchall,
24
+ };
25
+ });
26
+ }
27
+ ${(0, file_utils_1.ifTs)(jsOrTs, `interface LoaderPageProps {
28
+ params: Promise<Params>;
29
+ }`)}
30
+ export async function generateMetadata(
31
+ { params }${(0, file_utils_1.ifTs)(jsOrTs, `: LoaderPageProps`)},
32
+ parent${(0, file_utils_1.ifTs)(jsOrTs, `: ResolvingMetadata`)}
33
+ )${(0, file_utils_1.ifTs)(jsOrTs, `: Promise<Metadata>`)} {
34
+ const { componentData } = await getPlasmicData(params);
35
+
36
+ if (!componentData) {
37
+ return parent${(0, file_utils_1.ifTs)(jsOrTs, ` as Promise<Metadata>`)};
38
+ }
39
+ const pageMeta = componentData.entryCompMetas[0];
40
+ const metadata = await PLASMIC.unstable__generateMetadata(componentData, {
41
+ params: pageMeta.params ?? {},
42
+ query: {},
43
+ });
44
+
45
+ return { ...(await parent), ...metadata };
46
+ }
13
47
 
14
48
  export default async function PlasmicLoaderPage({
15
49
  params,
16
- searchParams,
17
- }${(0, file_utils_1.ifTs)(jsOrTs, `: {
18
- params?: { catchall: string[] | undefined };
19
- searchParams?: Record<string, string | string[]>;
20
- }`)}) {
21
- const plasmicComponentData = await fetchPlasmicComponentData(params?.catchall);
22
- if (!plasmicComponentData) {
23
- notFound();
24
- }
50
+ }${(0, file_utils_1.ifTs)(jsOrTs, `: LoaderPageProps`)}) {
51
+ const { pagePath, componentData } = await getPlasmicData(params);
25
52
 
26
- const { prefetchedData } = plasmicComponentData;
27
- if (prefetchedData.entryCompMetas.length === 0) {
53
+ if (!componentData) {
28
54
  notFound();
29
55
  }
56
+ const pageMeta = componentData.entryCompMetas[0];
57
+ const prefetchedQueryData = await PLASMIC.unstable__getServerQueriesData(
58
+ componentData,
59
+ {
60
+ pagePath,
61
+ params: pageMeta.params,
62
+ query: {},
63
+ }
64
+ );
30
65
 
31
- const pageMeta = prefetchedData.entryCompMetas[0];
32
66
  return (
33
67
  <ClientPlasmicRootProvider
34
- prefetchedData={prefetchedData}
35
- pageRoute={pageMeta.path}
68
+ prefetchedData={componentData}
69
+ prefetchedQueryData={prefetchedQueryData}
36
70
  pageParams={pageMeta.params}
37
- pageQuery={searchParams}
71
+ pageRoute={pageMeta.path}
38
72
  >
39
- <PlasmicComponent
40
- component={pageMeta.displayName}
41
- />
73
+ <PlasmicComponent component={pageMeta.displayName} />
42
74
  </ClientPlasmicRootProvider>
43
75
  );
44
76
  }
45
77
 
46
- async function fetchPlasmicComponentData(catchall${(0, file_utils_1.ifTs)(jsOrTs, ": string[] | undefined")}) {
47
- const plasmicPath = "/" + (catchall ? catchall.join("/") : "");
48
- const prefetchedData = await PLASMIC.maybeFetchComponentData(plasmicPath);
49
- if (!prefetchedData) {
50
- notFound();
51
- }
78
+ async function getPlasmicData(
79
+ params${(0, file_utils_1.ifTs)(jsOrTs, ": Promise<Params>")}
80
+ )${(0, file_utils_1.ifTs)(jsOrTs, ": Promise<{ pagePath: string; componentData?: ComponentRenderData }>")} {
81
+ const catchall = (await params).catchall;
82
+ const pagePath = catchall ? \`/\${catchall.join("/")}\` : "/";
52
83
 
53
- return { prefetchedData };
54
- }
84
+ const componentData = await PLASMIC.maybeFetchComponentData(pagePath);
55
85
 
56
- export async function generateStaticParams() {
57
- const pageModules = await PLASMIC.fetchPages();
58
- return pageModules.map((mod) => {
59
- const catchall =
60
- mod.path === "/" ? undefined : mod.path.substring(1).split("/");
61
- return {
62
- catchall,
63
- };
64
- });
86
+ if (!componentData || componentData.entryCompMetas.length === 0) {
87
+ return { pagePath };
88
+ }
89
+ return { pagePath, componentData };
65
90
  }
66
91
  `;
67
92
  }
@@ -21,7 +21,7 @@ import { PLASMIC } from "@/plasmic-init";
21
21
  * ClientPlasmicRootProvider is a Client Component that passes in the loader for you.
22
22
  *
23
23
  * Why? Props passed from Server to Client Components must be serializable.
24
- * https://beta.nextjs.org/docs/rendering/server-and-client-components#passing-props-from-server-to-client-components-serialization
24
+ * https://nextjs.org/docs/app/getting-started/server-and-client-components#passing-data-from-server-to-client-components
25
25
  * However, PlasmicRootProvider requires a loader, but the loader is NOT serializable.
26
26
  *
27
27
  * In a Server Component like app/<your-path>/path.tsx, rendering the following would not work:
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.makePlasmicInit_app_loader = void 0;
4
4
  function makePlasmicInit_app_loader(projectId, projectApiToken) {
5
5
  return `import { initPlasmicLoader } from "@plasmicapp/loader-nextjs/react-server-conditional";
6
+ import * as NextNavigation from "next/navigation";
6
7
 
7
8
  export const PLASMIC = initPlasmicLoader({
8
9
  projects: [
@@ -17,6 +18,9 @@ export const PLASMIC = initPlasmicLoader({
17
18
  // project, allowing you to see your designs without publishing. Please
18
19
  // only use this for development, as this is significantly slower.
19
20
  preview: false,
21
+
22
+ // Needed for Next.js app router support.
23
+ nextNavigation: NextNavigation,
20
24
  });
21
25
  `;
22
26
  }
@@ -41,7 +41,7 @@ exports.reactStrategy = {
41
41
  const projectName = path_1.default.basename(fullProjectPath);
42
42
  const parentDir = path_1.default.dirname(fullProjectPath);
43
43
  process.chdir(parentDir);
44
- const createCommand = `npx create-vite@latest ${projectName} --no-interactive`;
44
+ const createCommand = `npx create-vite@5 ${projectName} --no-interactive`;
45
45
  if (!template) {
46
46
  template = jsOrTs === "ts" ? "react-ts" : "react";
47
47
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-plasmic-app",
3
- "version": "0.0.134",
3
+ "version": "0.0.136",
4
4
  "description": "Create Plasmic-powered React apps",
5
5
  "main": "./dist/lib.js",
6
6
  "types": "./dist/lib.d.ts",
@@ -47,5 +47,5 @@
47
47
  "validate-npm-package-name": "^3.0.0",
48
48
  "yargs": "^16.2.0"
49
49
  },
50
- "gitHead": "d429f0c262533e0bcc1e2a18675c4e6277580ac6"
50
+ "gitHead": "1b5025833480c30a67137ad81b8008c4719b1730"
51
51
  }
package/src/index.ts CHANGED
@@ -244,8 +244,6 @@ async function run(): Promise<void> {
244
244
  }
245
245
  }
246
246
 
247
- // Get the projectId
248
- console.log();
249
247
  const projectInput = await maybePrompt<string>({
250
248
  name: "projectId",
251
249
  message: `If you don't have a project yet, create one by going to https://studio.plasmic.app/starters/blank
@@ -2,71 +2,108 @@ import { ifTs } from "../../../utils/file-utils";
2
2
  import { JsOrTs } from "../../../utils/types";
3
3
 
4
4
  export function makeCatchallPage_app_loader(jsOrTs: JsOrTs): string {
5
- return `import { PlasmicComponent } from "@plasmicapp/loader-nextjs";
6
- import { notFound } from "next/navigation";
7
- import { PLASMIC } from "@/plasmic-init";
5
+ return `import { PLASMIC } from "@/plasmic-init";
8
6
  import { ClientPlasmicRootProvider } from "@/plasmic-init-client";
7
+ import { ${ifTs(
8
+ jsOrTs,
9
+ `ComponentRenderData,`
10
+ )}PlasmicComponent } from "@plasmicapp/loader-nextjs";${ifTs(
11
+ jsOrTs,
12
+ `
13
+ import { Metadata, ResolvingMetadata } from "next";`
14
+ )}
15
+ import { notFound } from "next/navigation";
9
16
 
10
17
  // Use revalidate if you want incremental static regeneration
11
18
  export const revalidate = 60;
19
+ ${ifTs(
20
+ jsOrTs,
21
+ `interface Params {
22
+ catchall: string[] | undefined;
23
+ }`
24
+ )}
25
+ export async function generateStaticParams()${ifTs(
26
+ jsOrTs,
27
+ ": Promise<Params[]>"
28
+ )} {
29
+ const pageModules = await PLASMIC.fetchPages();
30
+ return pageModules.map((mod) => {
31
+ const catchall =
32
+ mod.path === "/" ? undefined : mod.path.substring(1).split("/");
33
+ return {
34
+ catchall,
35
+ };
36
+ });
37
+ }
38
+ ${ifTs(
39
+ jsOrTs,
40
+ `interface LoaderPageProps {
41
+ params: Promise<Params>;
42
+ }`
43
+ )}
44
+ export async function generateMetadata(
45
+ { params }${ifTs(jsOrTs, `: LoaderPageProps`)},
46
+ parent${ifTs(jsOrTs, `: ResolvingMetadata`)}
47
+ )${ifTs(jsOrTs, `: Promise<Metadata>`)} {
48
+ const { componentData } = await getPlasmicData(params);
49
+
50
+ if (!componentData) {
51
+ return parent${ifTs(jsOrTs, ` as Promise<Metadata>`)};
52
+ }
53
+ const pageMeta = componentData.entryCompMetas[0];
54
+ const metadata = await PLASMIC.unstable__generateMetadata(componentData, {
55
+ params: pageMeta.params ?? {},
56
+ query: {},
57
+ });
58
+
59
+ return { ...(await parent), ...metadata };
60
+ }
12
61
 
13
62
  export default async function PlasmicLoaderPage({
14
63
  params,
15
- searchParams,
16
- }${ifTs(
17
- jsOrTs,
18
- `: {
19
- params?: { catchall: string[] | undefined };
20
- searchParams?: Record<string, string | string[]>;
21
- }`
22
- )}) {
23
- const plasmicComponentData = await fetchPlasmicComponentData(params?.catchall);
24
- if (!plasmicComponentData) {
25
- notFound();
26
- }
64
+ }${ifTs(jsOrTs, `: LoaderPageProps`)}) {
65
+ const { pagePath, componentData } = await getPlasmicData(params);
27
66
 
28
- const { prefetchedData } = plasmicComponentData;
29
- if (prefetchedData.entryCompMetas.length === 0) {
67
+ if (!componentData) {
30
68
  notFound();
31
69
  }
70
+ const pageMeta = componentData.entryCompMetas[0];
71
+ const prefetchedQueryData = await PLASMIC.unstable__getServerQueriesData(
72
+ componentData,
73
+ {
74
+ pagePath,
75
+ params: pageMeta.params,
76
+ query: {},
77
+ }
78
+ );
32
79
 
33
- const pageMeta = prefetchedData.entryCompMetas[0];
34
80
  return (
35
81
  <ClientPlasmicRootProvider
36
- prefetchedData={prefetchedData}
37
- pageRoute={pageMeta.path}
82
+ prefetchedData={componentData}
83
+ prefetchedQueryData={prefetchedQueryData}
38
84
  pageParams={pageMeta.params}
39
- pageQuery={searchParams}
85
+ pageRoute={pageMeta.path}
40
86
  >
41
- <PlasmicComponent
42
- component={pageMeta.displayName}
43
- />
87
+ <PlasmicComponent component={pageMeta.displayName} />
44
88
  </ClientPlasmicRootProvider>
45
89
  );
46
90
  }
47
91
 
48
- async function fetchPlasmicComponentData(catchall${ifTs(
92
+ async function getPlasmicData(
93
+ params${ifTs(jsOrTs, ": Promise<Params>")}
94
+ )${ifTs(
49
95
  jsOrTs,
50
- ": string[] | undefined"
51
- )}) {
52
- const plasmicPath = "/" + (catchall ? catchall.join("/") : "");
53
- const prefetchedData = await PLASMIC.maybeFetchComponentData(plasmicPath);
54
- if (!prefetchedData) {
55
- notFound();
56
- }
96
+ ": Promise<{ pagePath: string; componentData?: ComponentRenderData }>"
97
+ )} {
98
+ const catchall = (await params).catchall;
99
+ const pagePath = catchall ? \`/\${catchall.join("/")}\` : "/";
57
100
 
58
- return { prefetchedData };
59
- }
101
+ const componentData = await PLASMIC.maybeFetchComponentData(pagePath);
60
102
 
61
- export async function generateStaticParams() {
62
- const pageModules = await PLASMIC.fetchPages();
63
- return pageModules.map((mod) => {
64
- const catchall =
65
- mod.path === "/" ? undefined : mod.path.substring(1).split("/");
66
- return {
67
- catchall,
68
- };
69
- });
103
+ if (!componentData || componentData.entryCompMetas.length === 0) {
104
+ return { pagePath };
105
+ }
106
+ return { pagePath, componentData };
70
107
  }
71
108
  `;
72
109
  }
@@ -20,7 +20,7 @@ import { PLASMIC } from "@/plasmic-init";
20
20
  * ClientPlasmicRootProvider is a Client Component that passes in the loader for you.
21
21
  *
22
22
  * Why? Props passed from Server to Client Components must be serializable.
23
- * https://beta.nextjs.org/docs/rendering/server-and-client-components#passing-props-from-server-to-client-components-serialization
23
+ * https://nextjs.org/docs/app/getting-started/server-and-client-components#passing-data-from-server-to-client-components
24
24
  * However, PlasmicRootProvider requires a loader, but the loader is NOT serializable.
25
25
  *
26
26
  * In a Server Component like app/<your-path>/path.tsx, rendering the following would not work:
@@ -3,6 +3,7 @@ export function makePlasmicInit_app_loader(
3
3
  projectApiToken: string
4
4
  ): string {
5
5
  return `import { initPlasmicLoader } from "@plasmicapp/loader-nextjs/react-server-conditional";
6
+ import * as NextNavigation from "next/navigation";
6
7
 
7
8
  export const PLASMIC = initPlasmicLoader({
8
9
  projects: [
@@ -17,6 +18,9 @@ export const PLASMIC = initPlasmicLoader({
17
18
  // project, allowing you to see your designs without publishing. Please
18
19
  // only use this for development, as this is significantly slower.
19
20
  preview: false,
21
+
22
+ // Needed for Next.js app router support.
23
+ nextNavigation: NextNavigation,
20
24
  });
21
25
  `;
22
26
  }
@@ -37,7 +37,7 @@ export const reactStrategy: CPAStrategy = {
37
37
  const parentDir = path.dirname(fullProjectPath);
38
38
  process.chdir(parentDir);
39
39
 
40
- const createCommand = `npx create-vite@latest ${projectName} --no-interactive`;
40
+ const createCommand = `npx create-vite@5 ${projectName} --no-interactive`;
41
41
 
42
42
  if (!template) {
43
43
  template = jsOrTs === "ts" ? "react-ts" : "react";
@@ -1,68 +0,0 @@
1
- import * as React from "react";
2
- import {
3
- PlasmicComponent,
4
- extractPlasmicQueryData,
5
- ComponentRenderData,
6
- PlasmicRootProvider,
7
- } from "@plasmicapp/loader-nextjs";
8
-
9
- import Error from "next/error";
10
- import { useRouter } from "next/router";
11
- import { PLASMIC } from "@/plasmic-init";
12
-
13
- export default function PlasmicLoaderPage(props) {
14
- const { plasmicData, queryCache } = props;
15
- const router = useRouter();
16
- if (!plasmicData || plasmicData.entryCompMetas.length === 0) {
17
- return <Error statusCode={404} />;
18
- }
19
- const pageMeta = plasmicData.entryCompMetas[0];
20
- return (
21
- <PlasmicRootProvider
22
- loader={PLASMIC}
23
- prefetchedData={plasmicData}
24
- prefetchedQueryData={queryCache}
25
- pageRoute={pageMeta.path}
26
- pageParams={pageMeta.params}
27
- pageQuery={router.query}
28
- >
29
- <PlasmicComponent component={pageMeta.displayName} />
30
- </PlasmicRootProvider>
31
- );
32
- }
33
-
34
- export const getStaticProps = async (context) => {
35
- const { catchall } = context.params ?? {};
36
- const plasmicPath = typeof catchall === 'string' ? catchall : Array.isArray(catchall) ? `/${catchall.join('/')}` : '/';
37
- const plasmicData = await PLASMIC.maybeFetchComponentData(plasmicPath);
38
- if (!plasmicData) {
39
- // non-Plasmic catch-all
40
- return { props: {} };
41
- }
42
- const pageMeta = plasmicData.entryCompMetas[0];
43
- // Cache the necessary data fetched for the page
44
- const queryCache = await extractPlasmicQueryData(
45
- <PlasmicRootProvider
46
- loader={PLASMIC}
47
- prefetchedData={plasmicData}
48
- pageRoute={pageMeta.path}
49
- pageParams={pageMeta.params}
50
- >
51
- <PlasmicComponent component={pageMeta.displayName} />
52
- </PlasmicRootProvider>
53
- );
54
- // Use revalidate if you want incremental static regeneration
55
- return { props: { plasmicData, queryCache }, revalidate: 60 };
56
- }
57
-
58
- export const getStaticPaths = async () => {
59
- const pageModules = await PLASMIC.fetchPages();
60
- return {
61
- paths: pageModules.map((mod) => ({
62
- params: {
63
- catchall: mod.path.substring(1).split("/"),
64
- },
65
- })),
66
- fallback: "blocking",
67
- };
68
- }
@@ -1,5 +0,0 @@
1
- // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2
-
3
- export default function handler(req, res) {
4
- res.status(200).json({ name: "John Doe" });
5
- }
@@ -1,7 +0,0 @@
1
- import * as React from 'react';
2
- import { PlasmicCanvasHost } from '@plasmicapp/loader-nextjs';
3
- import { PLASMIC } from '@/plasmic-init';
4
-
5
- export default function PlasmicHost() {
6
- return PLASMIC && <PlasmicCanvasHost />;
7
- }
@@ -1,72 +0,0 @@
1
- import * as React from "react";
2
- import {
3
- PlasmicComponent,
4
- extractPlasmicQueryData,
5
- ComponentRenderData,
6
- PlasmicRootProvider,
7
- } from "@plasmicapp/loader-nextjs";
8
- import type { GetStaticPaths, GetStaticProps } from "next";
9
-
10
- import Error from "next/error";
11
- import { useRouter } from "next/router";
12
- import { PLASMIC } from "@/plasmic-init";
13
-
14
- export default function PlasmicLoaderPage(props: {
15
- plasmicData?: ComponentRenderData;
16
- queryCache?: Record<string, unknown>;
17
- }) {
18
- const { plasmicData, queryCache } = props;
19
- const router = useRouter();
20
- if (!plasmicData || plasmicData.entryCompMetas.length === 0) {
21
- return <Error statusCode={404} />;
22
- }
23
- const pageMeta = plasmicData.entryCompMetas[0];
24
- return (
25
- <PlasmicRootProvider
26
- loader={PLASMIC}
27
- prefetchedData={plasmicData}
28
- prefetchedQueryData={queryCache}
29
- pageRoute={pageMeta.path}
30
- pageParams={pageMeta.params}
31
- pageQuery={router.query}
32
- >
33
- <PlasmicComponent component={pageMeta.displayName} />
34
- </PlasmicRootProvider>
35
- );
36
- }
37
-
38
- export const getStaticProps: GetStaticProps = async (context) => {
39
- const { catchall } = context.params ?? {};
40
- const plasmicPath = typeof catchall === 'string' ? catchall : Array.isArray(catchall) ? `/${catchall.join('/')}` : '/';
41
- const plasmicData = await PLASMIC.maybeFetchComponentData(plasmicPath);
42
- if (!plasmicData) {
43
- // non-Plasmic catch-all
44
- return { props: {} };
45
- }
46
- const pageMeta = plasmicData.entryCompMetas[0];
47
- // Cache the necessary data fetched for the page
48
- const queryCache = await extractPlasmicQueryData(
49
- <PlasmicRootProvider
50
- loader={PLASMIC}
51
- prefetchedData={plasmicData}
52
- pageRoute={pageMeta.path}
53
- pageParams={pageMeta.params}
54
- >
55
- <PlasmicComponent component={pageMeta.displayName} />
56
- </PlasmicRootProvider>
57
- );
58
- // Use revalidate if you want incremental static regeneration
59
- return { props: { plasmicData, queryCache }, revalidate: 60 };
60
- }
61
-
62
- export const getStaticPaths: GetStaticPaths = async () => {
63
- const pageModules = await PLASMIC.fetchPages();
64
- return {
65
- paths: pageModules.map((mod) => ({
66
- params: {
67
- catchall: mod.path.substring(1).split("/"),
68
- },
69
- })),
70
- fallback: "blocking",
71
- };
72
- }
@@ -1,13 +0,0 @@
1
- // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2
- import type { NextApiRequest, NextApiResponse } from "next";
3
-
4
- type Data = {
5
- name: string;
6
- };
7
-
8
- export default function handler(
9
- req: NextApiRequest,
10
- res: NextApiResponse<Data>,
11
- ) {
12
- res.status(200).json({ name: "John Doe" });
13
- }
@@ -1,7 +0,0 @@
1
- import * as React from 'react';
2
- import { PlasmicCanvasHost } from '@plasmicapp/loader-nextjs';
3
- import { PLASMIC } from '@/plasmic-init';
4
-
5
- export default function PlasmicHost() {
6
- return PLASMIC && <PlasmicCanvasHost />;
7
- }