create-puck-app 0.22.0-canary.f4f83ac1 → 0.22.0
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.
- package/index.js +0 -4
- package/package.json +2 -2
- package/templates/next-ai/package.json.hbs +2 -2
- package/templates/react-router-ai/package.json.hbs +2 -2
- package/templates/gitignore +0 -8
- package/templates/next/.eslintrc.js +0 -4
- package/templates/next/README.md +0 -38
- package/templates/next/app/[...puckPath]/client.tsx +0 -9
- package/templates/next/app/[...puckPath]/page.tsx +0 -49
- package/templates/next/app/favicon.ico +0 -0
- package/templates/next/app/layout.tsx +0 -13
- package/templates/next/app/page.tsx +0 -1
- package/templates/next/app/puck/[...puckPath]/client.tsx +0 -20
- package/templates/next/app/puck/[...puckPath]/page.tsx +0 -44
- package/templates/next/app/puck/api/route.ts +0 -25
- package/templates/next/app/puck/page.tsx +0 -3
- package/templates/next/app/styles.css +0 -3
- package/templates/next/database.json +0 -1
- package/templates/next/gitignore +0 -34
- package/templates/next/lib/get-page.ts +0 -11
- package/templates/next/next-env.d.ts +0 -6
- package/templates/next/next.config.js +0 -3
- package/templates/next/proxy.ts +0 -27
- package/templates/next/puck.config.tsx +0 -25
- package/templates/next/tsconfig/base.json +0 -20
- package/templates/next/tsconfig/nextjs.json +0 -21
- package/templates/next/tsconfig.json +0 -8
- package/templates/next-ai/.env.example +0 -2
- package/templates/next-ai/.eslintrc.js +0 -4
- package/templates/next-ai/README.md +0 -60
- package/templates/next-ai/app/[...puckPath]/client.tsx +0 -9
- package/templates/next-ai/app/[...puckPath]/page.tsx +0 -49
- package/templates/next-ai/app/api/pages/route.ts +0 -26
- package/templates/next-ai/app/api/puck/[...all]/route.ts +0 -13
- package/templates/next-ai/app/layout.tsx +0 -13
- package/templates/next-ai/app/page.tsx +0 -1
- package/templates/next-ai/app/puck/[...puckPath]/client.tsx +0 -25
- package/templates/next-ai/app/puck/[...puckPath]/page.tsx +0 -45
- package/templates/next-ai/app/puck/page.tsx +0 -3
- package/templates/next-ai/app/styles.css +0 -3
- package/templates/next-ai/database.json +0 -1
- package/templates/next-ai/gitignore +0 -34
- package/templates/next-ai/lib/get-page.ts +0 -11
- package/templates/next-ai/next-env.d.ts +0 -6
- package/templates/next-ai/next.config.js +0 -3
- package/templates/next-ai/proxy.ts +0 -27
- package/templates/next-ai/public/favicon.ico +0 -0
- package/templates/next-ai/puck.config.tsx +0 -25
- package/templates/next-ai/tsconfig/base.json +0 -20
- package/templates/next-ai/tsconfig/nextjs.json +0 -21
- package/templates/next-ai/tsconfig.json +0 -8
- package/templates/react-router/README.md +0 -35
- package/templates/react-router/app/components/puck-render.tsx +0 -8
- package/templates/react-router/app/lib/pages.server.ts +0 -29
- package/templates/react-router/app/lib/resolve-puck-path.server.ts +0 -19
- package/templates/react-router/app/root.tsx +0 -65
- package/templates/react-router/app/routes/_index.tsx +0 -31
- package/templates/react-router/app/routes/puck-splat.tsx +0 -95
- package/templates/react-router/app/routes.ts +0 -7
- package/templates/react-router/database.json +0 -1
- package/templates/react-router/gitignore +0 -6
- package/templates/react-router/public/favicon.ico +0 -0
- package/templates/react-router/puck.config.tsx +0 -23
- package/templates/react-router/react-router.config.ts +0 -7
- package/templates/react-router/vite.config.ts +0 -7
- package/templates/react-router-ai/.env.example +0 -2
- package/templates/react-router-ai/README.md +0 -57
- package/templates/react-router-ai/app/components/puck-render.tsx +0 -8
- package/templates/react-router-ai/app/lib/pages.server.ts +0 -29
- package/templates/react-router-ai/app/lib/resolve-puck-path.server.ts +0 -19
- package/templates/react-router-ai/app/root.tsx +0 -65
- package/templates/react-router-ai/app/routes/_index.tsx +0 -31
- package/templates/react-router-ai/app/routes/api.puck.ts +0 -13
- package/templates/react-router-ai/app/routes/puck-splat.tsx +0 -101
- package/templates/react-router-ai/app/routes.ts +0 -8
- package/templates/react-router-ai/database.json +0 -1
- package/templates/react-router-ai/gitignore +0 -6
- package/templates/react-router-ai/public/favicon.ico +0 -0
- package/templates/react-router-ai/puck.config.tsx +0 -23
- package/templates/react-router-ai/react-router.config.ts +0 -7
- package/templates/react-router-ai/vite.config.ts +0 -7
- package/templates/remix/.eslintrc.cjs +0 -4
- package/templates/remix/README.md +0 -42
- package/templates/remix/app/entry.client.tsx +0 -18
- package/templates/remix/app/entry.server.tsx +0 -137
- package/templates/remix/app/models/page.server.ts +0 -27
- package/templates/remix/app/puck.config.tsx +0 -25
- package/templates/remix/app/root.tsx +0 -36
- package/templates/remix/app/routes/$puckPath.tsx +0 -2
- package/templates/remix/app/routes/$puckPath_.edit.tsx +0 -5
- package/templates/remix/app/routes/_index.tsx +0 -34
- package/templates/remix/app/routes/edit.tsx +0 -64
- package/templates/remix/app/styles/shared.css +0 -3
- package/templates/remix/database.json +0 -1
- package/templates/remix/gitignore +0 -6
- package/templates/remix/package.json.hbs +0 -35
- package/templates/remix/public/favicon.ico +0 -0
- package/templates/remix/remix.config.js +0 -12
- package/templates/remix/remix.env.d.ts +0 -2
- package/templates/remix/tsconfig.json +0 -22
- package/templates/remix-ai/.env.example +0 -2
- package/templates/remix-ai/.eslintrc.cjs +0 -4
- package/templates/remix-ai/README.md +0 -64
- package/templates/remix-ai/app/entry.client.tsx +0 -18
- package/templates/remix-ai/app/entry.server.tsx +0 -137
- package/templates/remix-ai/app/models/page.server.ts +0 -27
- package/templates/remix-ai/app/puck.config.tsx +0 -25
- package/templates/remix-ai/app/root.tsx +0 -36
- package/templates/remix-ai/app/routes/$puckPath.tsx +0 -2
- package/templates/remix-ai/app/routes/$puckPath_.edit.tsx +0 -2
- package/templates/remix-ai/app/routes/_index.tsx +0 -34
- package/templates/remix-ai/app/routes/api.puck.$.tsx +0 -13
- package/templates/remix-ai/app/routes/edit.tsx +0 -70
- package/templates/remix-ai/app/styles/shared.css +0 -3
- package/templates/remix-ai/database.json +0 -1
- package/templates/remix-ai/gitignore +0 -6
- package/templates/remix-ai/package.json.hbs +0 -37
- package/templates/remix-ai/public/favicon.ico +0 -0
- package/templates/remix-ai/remix.config.js +0 -12
- package/templates/remix-ai/remix.env.d.ts +0 -2
- package/templates/remix-ai/tsconfig.json +0 -22
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-puck-app",
|
|
3
|
-
"version": "0.22.0
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"author": "Chris Villa <chris@puckeditor.com>",
|
|
5
5
|
"repository": "puckeditor/puck",
|
|
6
6
|
"bugs": "https://github.com/puckeditor/puck/issues",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"commander": "^10.0.1",
|
|
26
|
-
"glob": "^
|
|
26
|
+
"glob": "^12.0.0",
|
|
27
27
|
"handlebars": "^4.7.7",
|
|
28
28
|
"inquirer": "^9.2.7",
|
|
29
29
|
"prettier": "^2.8.8"
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@puckeditor/core": "{{puckVersion}}",
|
|
12
|
-
"@puckeditor/cloud-client": "^0.
|
|
13
|
-
"@puckeditor/plugin-ai": "^0.
|
|
12
|
+
"@puckeditor/cloud-client": "^0.7.0",
|
|
13
|
+
"@puckeditor/plugin-ai": "^0.7.0",
|
|
14
14
|
"classnames": "^2.3.2",
|
|
15
15
|
"next": "^16.0.8",
|
|
16
16
|
"react": "^19.2.1",
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"@puckeditor/core": "{{puckVersion}}",
|
|
14
|
-
"@puckeditor/cloud-client": "^0.
|
|
15
|
-
"@puckeditor/plugin-ai": "^0.
|
|
14
|
+
"@puckeditor/cloud-client": "^0.7.0",
|
|
15
|
+
"@puckeditor/plugin-ai": "^0.7.0",
|
|
16
16
|
"@react-router/node": "^7.5.3",
|
|
17
17
|
"@react-router/serve": "^7.5.3",
|
|
18
18
|
"isbot": "^5",
|
package/templates/gitignore
DELETED
package/templates/next/README.md
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
# `next` recipe
|
|
2
|
-
|
|
3
|
-
The `next` recipe showcases one of the most powerful ways to implement Puck using to provide an authoring tool for any route in your Next app.
|
|
4
|
-
|
|
5
|
-
## Demonstrates
|
|
6
|
-
|
|
7
|
-
- Next.js App Router implementation
|
|
8
|
-
- JSON database implementation with HTTP API
|
|
9
|
-
- Catch-all routes to use puck for any route on the platform
|
|
10
|
-
- Incremental static regeneration (ISR) for all Puck pages
|
|
11
|
-
|
|
12
|
-
## Usage
|
|
13
|
-
|
|
14
|
-
Run the generator and enter `next` when prompted
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
npx create-puck-app my-app
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
Start the server
|
|
21
|
-
|
|
22
|
-
```
|
|
23
|
-
yarn dev
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
Navigate to the homepage at https://localhost:3000. To edit the homepage, access the Puck editor at https://localhost:3000/edit.
|
|
27
|
-
|
|
28
|
-
You can do this for any route on the application, **even if the page doesn't exist**. For example, visit https://localhost:3000/hello/world and you'll receive a 404. You can author and publish a page by visiting https://localhost:3000/hello/world/edit. After publishing, go back to the original URL to see your page.
|
|
29
|
-
|
|
30
|
-
## Using this recipe
|
|
31
|
-
|
|
32
|
-
To adopt this recipe you will need to:
|
|
33
|
-
|
|
34
|
-
- **IMPORTANT** Add authentication to `/edit` routes. This can be done by modifying the example API routes in `/app/puck/api/route.ts` and server component in `/app/puck/[...puckPath]/page.tsx`. **If you don't do this, Puck will be completely public.**
|
|
35
|
-
- Integrate your database into the API calls in `/app/puck/api/route.ts`
|
|
36
|
-
- Implement a custom puck configuration in `puck.config.tsx`
|
|
37
|
-
|
|
38
|
-
By default, this recipe will generate static pages by setting `dynamic` to [`force-static`](https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#dynamic) in the `/app/[...puckPath]/page.tsx`. This will strip headers and cookies. If you need dynamic pages, you can delete this.
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This file implements a catch-all route that renders the user-facing pages
|
|
3
|
-
* generated by Puck. For any route visited (with exception of other hardcoded
|
|
4
|
-
* pages in /app), it will check your database (via `getPage`) for a Puck page
|
|
5
|
-
* and render it using <Render>.
|
|
6
|
-
*
|
|
7
|
-
* All routes produced by this page are statically rendered using incremental
|
|
8
|
-
* static site generation. After the first visit, the page will be cached as
|
|
9
|
-
* a static file. Subsequent visits will receive the cache. Publishing a page
|
|
10
|
-
* will invalidate the cache as the page is written in /api/puck/route.ts
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import { Client } from "./client";
|
|
14
|
-
import { notFound } from "next/navigation";
|
|
15
|
-
import { Metadata } from "next";
|
|
16
|
-
import { getPage } from "../../lib/get-page";
|
|
17
|
-
|
|
18
|
-
export async function generateMetadata({
|
|
19
|
-
params,
|
|
20
|
-
}: {
|
|
21
|
-
params: Promise<{ puckPath: string[] }>;
|
|
22
|
-
}): Promise<Metadata> {
|
|
23
|
-
const { puckPath = [] } = await params;
|
|
24
|
-
const path = `/${puckPath.join("/")}`;
|
|
25
|
-
|
|
26
|
-
return {
|
|
27
|
-
title: getPage(path)?.root.props?.title,
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export default async function Page({
|
|
32
|
-
params,
|
|
33
|
-
}: {
|
|
34
|
-
params: Promise<{ puckPath: string[] }>;
|
|
35
|
-
}) {
|
|
36
|
-
const { puckPath = [] } = await params;
|
|
37
|
-
const path = `/${puckPath.join("/")}`;
|
|
38
|
-
const data = getPage(path);
|
|
39
|
-
|
|
40
|
-
if (!data) {
|
|
41
|
-
return notFound();
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return <Client data={data} />;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Force Next.js to produce static pages: https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#dynamic
|
|
48
|
-
// Delete this if you need dynamic rendering, such as access to headers or cookies
|
|
49
|
-
export const dynamic = "force-static";
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default, generateMetadata } from "./[...puckPath]/page";
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import type { Data } from "@puckeditor/core";
|
|
4
|
-
import { Puck } from "@puckeditor/core";
|
|
5
|
-
import config from "../../../puck.config";
|
|
6
|
-
|
|
7
|
-
export function Client({ path, data }: { path: string; data: Partial<Data> }) {
|
|
8
|
-
return (
|
|
9
|
-
<Puck
|
|
10
|
-
config={config}
|
|
11
|
-
data={data}
|
|
12
|
-
onPublish={async (data) => {
|
|
13
|
-
await fetch("/puck/api", {
|
|
14
|
-
method: "post",
|
|
15
|
-
body: JSON.stringify({ data, path }),
|
|
16
|
-
});
|
|
17
|
-
}}
|
|
18
|
-
/>
|
|
19
|
-
);
|
|
20
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This file implements a *magic* catch-all route that renders the Puck editor.
|
|
3
|
-
*
|
|
4
|
-
* This route exposes /puck/[...puckPath], but is disabled by middleware.ts. The middleware
|
|
5
|
-
* then rewrites all URL requests ending in `/edit` to this route, allowing you to visit any
|
|
6
|
-
* page in your application and add /edit to the end to spin up a Puck editor.
|
|
7
|
-
*
|
|
8
|
-
* This approach enables public pages to be statically rendered whilst the /puck route can
|
|
9
|
-
* remain dynamic.
|
|
10
|
-
*
|
|
11
|
-
* NB this route is public, and you will need to add authentication
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import "@puckeditor/core/puck.css";
|
|
15
|
-
import { Client } from "./client";
|
|
16
|
-
import { Metadata } from "next";
|
|
17
|
-
import { getPage } from "../../../lib/get-page";
|
|
18
|
-
|
|
19
|
-
export async function generateMetadata({
|
|
20
|
-
params,
|
|
21
|
-
}: {
|
|
22
|
-
params: Promise<{ puckPath: string[] }>;
|
|
23
|
-
}): Promise<Metadata> {
|
|
24
|
-
const { puckPath = [] } = await params;
|
|
25
|
-
const path = `/${puckPath.join("/")}`;
|
|
26
|
-
|
|
27
|
-
return {
|
|
28
|
-
title: "Puck: " + path,
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export default async function Page({
|
|
33
|
-
params,
|
|
34
|
-
}: {
|
|
35
|
-
params: Promise<{ puckPath: string[] }>;
|
|
36
|
-
}) {
|
|
37
|
-
const { puckPath = [] } = await params;
|
|
38
|
-
const path = `/${puckPath.join("/")}`;
|
|
39
|
-
const data = getPage(path);
|
|
40
|
-
|
|
41
|
-
return <Client path={path} data={data || {}} />;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export const dynamic = "force-dynamic";
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { revalidatePath } from "next/cache";
|
|
2
|
-
import { NextResponse } from "next/server";
|
|
3
|
-
import fs from "fs";
|
|
4
|
-
|
|
5
|
-
export async function POST(request: Request) {
|
|
6
|
-
const payload = await request.json();
|
|
7
|
-
|
|
8
|
-
const existingData = JSON.parse(
|
|
9
|
-
fs.existsSync("database.json")
|
|
10
|
-
? fs.readFileSync("database.json", "utf-8")
|
|
11
|
-
: "{}"
|
|
12
|
-
);
|
|
13
|
-
|
|
14
|
-
const updatedData = {
|
|
15
|
-
...existingData,
|
|
16
|
-
[payload.path]: payload.data,
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
fs.writeFileSync("database.json", JSON.stringify(updatedData));
|
|
20
|
-
|
|
21
|
-
// Purge Next.js cache
|
|
22
|
-
revalidatePath(payload.path);
|
|
23
|
-
|
|
24
|
-
return NextResponse.json({ status: "ok" });
|
|
25
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"/":{"content":[{"type":"HeadingBlock","props":{"title":"Edit this page by adding /edit to the end of the URL","id":"HeadingBlock-1694032984497"}}],"root":{"props": {"title":""}}}}
|
package/templates/next/gitignore
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
|
2
|
-
|
|
3
|
-
# dependencies
|
|
4
|
-
/node_modules
|
|
5
|
-
/.pnp
|
|
6
|
-
.pnp.js
|
|
7
|
-
|
|
8
|
-
# testing
|
|
9
|
-
/coverage
|
|
10
|
-
|
|
11
|
-
# next.js
|
|
12
|
-
/.next/
|
|
13
|
-
/out/
|
|
14
|
-
|
|
15
|
-
# production
|
|
16
|
-
/build
|
|
17
|
-
|
|
18
|
-
# misc
|
|
19
|
-
.DS_Store
|
|
20
|
-
*.pem
|
|
21
|
-
|
|
22
|
-
# debug
|
|
23
|
-
npm-debug.log*
|
|
24
|
-
yarn-debug.log*
|
|
25
|
-
yarn-error.log*
|
|
26
|
-
|
|
27
|
-
# local env files
|
|
28
|
-
.env.local
|
|
29
|
-
.env.development.local
|
|
30
|
-
.env.test.local
|
|
31
|
-
.env.production.local
|
|
32
|
-
|
|
33
|
-
# vercel
|
|
34
|
-
.vercel
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { Data } from "@puckeditor/core";
|
|
2
|
-
import fs from "fs";
|
|
3
|
-
|
|
4
|
-
// Replace with call to your database
|
|
5
|
-
export const getPage = (path: string) => {
|
|
6
|
-
const allData: Record<string, Data> | null = fs.existsSync("database.json")
|
|
7
|
-
? JSON.parse(fs.readFileSync("database.json", "utf-8"))
|
|
8
|
-
: null;
|
|
9
|
-
|
|
10
|
-
return allData ? allData[path] : null;
|
|
11
|
-
};
|
package/templates/next/proxy.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { NextResponse } from "next/server";
|
|
2
|
-
|
|
3
|
-
import type { NextRequest } from "next/server";
|
|
4
|
-
|
|
5
|
-
export async function proxy(req: NextRequest) {
|
|
6
|
-
const res = NextResponse.next({ request: req });
|
|
7
|
-
|
|
8
|
-
if (req.method === "GET") {
|
|
9
|
-
// Rewrite routes that match "/[...puckPath]/edit" to "/puck/[...puckPath]"
|
|
10
|
-
if (req.nextUrl.pathname.endsWith("/edit")) {
|
|
11
|
-
const pathWithoutEdit = req.nextUrl.pathname.slice(
|
|
12
|
-
0,
|
|
13
|
-
req.nextUrl.pathname.length - 5
|
|
14
|
-
);
|
|
15
|
-
const pathWithEditPrefix = `/puck${pathWithoutEdit}`;
|
|
16
|
-
|
|
17
|
-
return NextResponse.rewrite(new URL(pathWithEditPrefix, req.url));
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// Disable "/puck/[...puckPath]"
|
|
21
|
-
if (req.nextUrl.pathname.startsWith("/puck")) {
|
|
22
|
-
return NextResponse.redirect(new URL("/", req.url));
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return res;
|
|
27
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import type { Config } from "@puckeditor/core";
|
|
2
|
-
|
|
3
|
-
type Props = {
|
|
4
|
-
HeadingBlock: { title: string };
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
export const config: Config<Props> = {
|
|
8
|
-
components: {
|
|
9
|
-
HeadingBlock: {
|
|
10
|
-
fields: {
|
|
11
|
-
title: { type: "text" },
|
|
12
|
-
},
|
|
13
|
-
defaultProps: {
|
|
14
|
-
title: "Heading",
|
|
15
|
-
},
|
|
16
|
-
render: ({ title }) => (
|
|
17
|
-
<div style={{ padding: 64 }}>
|
|
18
|
-
<h1>{title}</h1>
|
|
19
|
-
</div>
|
|
20
|
-
),
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export default config;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
-
"display": "Default",
|
|
4
|
-
"compilerOptions": {
|
|
5
|
-
"composite": false,
|
|
6
|
-
"declaration": true,
|
|
7
|
-
"declarationMap": true,
|
|
8
|
-
"esModuleInterop": true,
|
|
9
|
-
"forceConsistentCasingInFileNames": true,
|
|
10
|
-
"inlineSources": false,
|
|
11
|
-
"isolatedModules": true,
|
|
12
|
-
"moduleResolution": "node",
|
|
13
|
-
"noUnusedLocals": false,
|
|
14
|
-
"noUnusedParameters": false,
|
|
15
|
-
"preserveWatchOutput": true,
|
|
16
|
-
"skipLibCheck": true,
|
|
17
|
-
"strict": true
|
|
18
|
-
},
|
|
19
|
-
"exclude": ["node_modules"]
|
|
20
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
-
"display": "Next.js",
|
|
4
|
-
"extends": "./base.json",
|
|
5
|
-
"compilerOptions": {
|
|
6
|
-
"plugins": [{ "name": "next" }],
|
|
7
|
-
"allowJs": true,
|
|
8
|
-
"declaration": false,
|
|
9
|
-
"declarationMap": false,
|
|
10
|
-
"incremental": true,
|
|
11
|
-
"jsx": "preserve",
|
|
12
|
-
"lib": ["dom", "dom.iterable", "esnext"],
|
|
13
|
-
"module": "esnext",
|
|
14
|
-
"noEmit": true,
|
|
15
|
-
"resolveJsonModule": true,
|
|
16
|
-
"strict": false,
|
|
17
|
-
"target": "es5"
|
|
18
|
-
},
|
|
19
|
-
"include": ["src", "next-env.d.ts"],
|
|
20
|
-
"exclude": ["node_modules"]
|
|
21
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
# `next-ai` recipe
|
|
2
|
-
|
|
3
|
-
The `next-ai` recipe showcases one of the most powerful ways to combine Puck and [Puck AI](https://puckeditor.com/docs/ai/overview): providing an authoring tool with AI page generation capabilities for any route in your Next app.
|
|
4
|
-
|
|
5
|
-
## Demonstrates
|
|
6
|
-
|
|
7
|
-
- Puck AI integration for generating pages with AI
|
|
8
|
-
- Next.js App Router implementation
|
|
9
|
-
- JSON database implementation with HTTP API
|
|
10
|
-
- Catch-all routes to use puck for any route on the platform
|
|
11
|
-
- Incremental static regeneration (ISR) for all Puck pages
|
|
12
|
-
|
|
13
|
-
## Usage
|
|
14
|
-
|
|
15
|
-
Run the generator and select `Next.js` when prompted
|
|
16
|
-
|
|
17
|
-
```
|
|
18
|
-
npx create-puck-app my-app
|
|
19
|
-
|
|
20
|
-
? Which recipe would you like to use?
|
|
21
|
-
❯ Next.js
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
Confirm you want to use Puck AI
|
|
25
|
-
|
|
26
|
-
```
|
|
27
|
-
? Would you like to use Puck AI? (Y/n) Y
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
Start the server
|
|
31
|
-
|
|
32
|
-
```
|
|
33
|
-
cd my-app
|
|
34
|
-
yarn dev
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
### Set up Puck AI
|
|
38
|
-
|
|
39
|
-
Create a [Puck account](https://cloud.puckeditor.com) and [obtain an API key](https://cloud.puckeditor.com/api-keys).
|
|
40
|
-
|
|
41
|
-
Create a `.env.local` file in the root of your project and add your API key:
|
|
42
|
-
|
|
43
|
-
```
|
|
44
|
-
PUCK_API_KEY=your-api-key
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
Navigate to the homepage at https://localhost:3000. To edit the homepage, access the Puck editor at https://localhost:3000/edit, and select the AI button in the left navigation bar to generate content for the page using Puck AI.
|
|
48
|
-
|
|
49
|
-
You can do this for any route on the application, **even if the page doesn't exist**. For example, visit https://localhost:3000/hello/world and you'll receive a 404. You can author and publish a page by visiting https://localhost:3000/hello/world/edit. After publishing, go back to the original URL to see your page.
|
|
50
|
-
|
|
51
|
-
## Using this recipe
|
|
52
|
-
|
|
53
|
-
To adopt this recipe you will need to:
|
|
54
|
-
|
|
55
|
-
- **IMPORTANT** Add authentication to `/edit` routes. This can be done by modifying the example API routes in `/app/puck/api/route.ts` and server component in `/app/puck/[...puckPath]/page.tsx`. **If you don't do this, Puck will be completely public.**
|
|
56
|
-
- Integrate your database into the API calls in `/app/puck/api/route.ts`
|
|
57
|
-
- Implement a custom puck configuration in `puck.config.tsx`
|
|
58
|
-
- Add business context for the AI generation in `/app/api/puck/[...all]/route.ts`
|
|
59
|
-
|
|
60
|
-
By default, this recipe will generate static pages by setting `dynamic` to [`force-static`](https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#dynamic) in the `/app/[...puckPath]/page.tsx`. This will strip headers and cookies. If you need dynamic pages, you can delete this.
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This file implements a catch-all route that renders the user-facing pages
|
|
3
|
-
* generated by Puck. For any route visited (with exception of other hardcoded
|
|
4
|
-
* pages in /app), it will check your database (via `getPage`) for a Puck page
|
|
5
|
-
* and render it using <Render>.
|
|
6
|
-
*
|
|
7
|
-
* All routes produced by this page are statically rendered using incremental
|
|
8
|
-
* static site generation. After the first visit, the page will be cached as
|
|
9
|
-
* a static file. Subsequent visits will receive the cache. Publishing a page
|
|
10
|
-
* will invalidate the cache as the page is written in /api/puck/route.ts
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import { Client } from "./client";
|
|
14
|
-
import { notFound } from "next/navigation";
|
|
15
|
-
import { Metadata } from "next";
|
|
16
|
-
import { getPage } from "../../lib/get-page";
|
|
17
|
-
|
|
18
|
-
export async function generateMetadata({
|
|
19
|
-
params,
|
|
20
|
-
}: {
|
|
21
|
-
params: Promise<{ puckPath: string[] }>;
|
|
22
|
-
}): Promise<Metadata> {
|
|
23
|
-
const { puckPath = [] } = await params;
|
|
24
|
-
const path = `/${puckPath.join("/")}`;
|
|
25
|
-
|
|
26
|
-
return {
|
|
27
|
-
title: getPage(path)?.root.props?.title,
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export default async function Page({
|
|
32
|
-
params,
|
|
33
|
-
}: {
|
|
34
|
-
params: Promise<{ puckPath: string[] }>;
|
|
35
|
-
}) {
|
|
36
|
-
const { puckPath = [] } = await params;
|
|
37
|
-
const path = `/${puckPath.join("/")}`;
|
|
38
|
-
const data = getPage(path);
|
|
39
|
-
|
|
40
|
-
if (!data) {
|
|
41
|
-
return notFound();
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return <Client data={data} />;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Force Next.js to produce static pages: https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#dynamic
|
|
48
|
-
// Delete this if you need dynamic rendering, such as access to headers or cookies
|
|
49
|
-
export const dynamic = "force-static";
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { revalidatePath } from "next/cache";
|
|
2
|
-
import { NextResponse } from "next/server";
|
|
3
|
-
import fs from "fs";
|
|
4
|
-
|
|
5
|
-
// Saves page data to a JSON file, replace this with your own database logic
|
|
6
|
-
export async function POST(request: Request) {
|
|
7
|
-
const payload = await request.json();
|
|
8
|
-
|
|
9
|
-
const existingData = JSON.parse(
|
|
10
|
-
fs.existsSync("database.json")
|
|
11
|
-
? fs.readFileSync("database.json", "utf-8")
|
|
12
|
-
: "{}"
|
|
13
|
-
);
|
|
14
|
-
|
|
15
|
-
const updatedData = {
|
|
16
|
-
...existingData,
|
|
17
|
-
[payload.path]: payload.data,
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
fs.writeFileSync("database.json", JSON.stringify(updatedData));
|
|
21
|
-
|
|
22
|
-
// Purge Next.js cache
|
|
23
|
-
revalidatePath(payload.path);
|
|
24
|
-
|
|
25
|
-
return NextResponse.json({ status: "ok" });
|
|
26
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { NextRequest } from "next/server";
|
|
2
|
-
import { puckHandler } from "@puckeditor/cloud-client";
|
|
3
|
-
|
|
4
|
-
// Handles all requests for Puck AI
|
|
5
|
-
// Learn more: https://puckeditor.com/docs/ai/getting-started
|
|
6
|
-
export const POST = (request: NextRequest) => {
|
|
7
|
-
return puckHandler(request, {
|
|
8
|
-
ai: {
|
|
9
|
-
// Replace with your business context
|
|
10
|
-
context: "We are Google. You create Google landing pages.",
|
|
11
|
-
},
|
|
12
|
-
});
|
|
13
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default, generateMetadata } from "./[...puckPath]/page";
|