-
similar to my previous discussion I want to create a starter template for new and exiting devs that want to use Keystone embedded into a NextJs app, while still retaining functionality of the Admin UI.
Borisno2I've taken a lot of inspiration from borisno2's Drama Club Repo, and wanted to create a stripped down version for anyone to take and build off of. AIO FrameworkI am very keen on the idea of running keystone inside the Next App and having the Keystone Dashboard UI accessible via What worksSo far I have setup a Next 14 app to work side by side with a Keystone app
Routing Keystone's UIThis is one of the trickier parts that I do not understand. Take a look at next.config.mjs const KEYSTONE_URL = process.env.KEYSTONE_URL || 'http://localhost:3001'
/** @type {import('next').NextConfig} */
const nextConfig = {
// serverExternalPackages: ['graphql'],
experimental: {
// without this, 'Error: Expected Upload to be a GraphQL nullable type.'
serverComponentsExternalPackages: ['graphql'],
},
eslint: {
ignoreDuringBuilds: true,
},
typescript: {
ignoreBuildErrors: true,
},
async rewrites() {
return {
beforeFiles: [],
fallback: [
{
source: '/admin',
destination: `${KEYSTONE_URL}/admin`,
},
{
source: '/admin/:admin*',
destination: `${KEYSTONE_URL}/admin/:admin*`,
},
],
afterFiles: [],
}
},
};
export default nextConfig; Using TurboTaking a look back at Borisno2's Drama Club Repo, I see he has a single script that launches all dev services. Here is my rendition "scripts": {
"ks:watch": "keystone dev --no-server",
"ks:nextdev": "next dev .keystone/admin --port 3001",
"n:dev": "next dev -p 3000",
"dev": "turbo ks:watch ks:nextdev n:dev",
} Running the commands separately revels errors next dev .keystone/admin --port 3001Error in Terminal GET / 200 in 9ms
POST /api/graphql 404 in 7853ms
POST /api/graphql 404 in 7851ms Error in Browser Unhandled Runtime Error
Error: An error occurred when loading Admin Metadata
Call Stack
useKeystone
..\node_modules\.pnpm\@[email protected]_@pri_58e2e8f8c13e7b27abab6294bec5bf80\node_modules\@keystone-6\core\admin-ui\context\dist\keystone-6-core-admin-ui-context.esm.js (321:1)
HomePage
..\node_modules\.pnpm\@[email protected]_@pri_58e2e8f8c13e7b27abab6294bec5bf80\node_modules\@keystone-6\core\___internal-do-not-use-will-break-in-patch\admin-ui\pages\HomePage\dist\keystone-6-core-___internal-do-not-use-will-break-in-patch-admin-ui-pages-HomePage.esm.js (119:18) keystone dev --no-serverError in Terminal TypeError: Error trying to prepare the Admin UI
at initKeystone (I:\vscode\Keystone-Next-Auth-AIO-Exammple\node_modules\.pnpm\@[email protected]_@pri_58e2e8f8c13e7b27abab6294bec5bf80\node_modules\@keystone-6\core\scripts\cli\dist\keystone-6-core-scripts-cli.cjs.dev.js:1148:45)
at async dev (I:\vscode\Keystone-Next-Auth-AIO-Exammple\node_modules\.pnpm\@[email protected]_@pri_58e2e8f8c13e7b27abab6294bec5bf80\node_modules\@keystone-6\core\scripts\cli\dist\keystone-6-core-scripts-cli.cjs.dev.js:1294:5)
at async main (I:\vscode\Keystone-Next-Auth-AIO-Exammple\node_modules\.pnpm\@[email protected]_@pri_58e2e8f8c13e7b27abab6294bec5bf80\node_modules\@keystone-6\core\scripts\dist\keystone-6-core-scripts.cjs.dev.js:70:3)
ELIFECYCLE Command failed with exit code 1. I understand the theory. Using Next to launch launch the generated Keystone files 2 Next ServersI tried running these 2 commands in separate windows
Next app :3000
GET /admin 404 in 7ms Keystone app :3001going to Error in Terminal GET / 200 in 8ms
POST /api/graphql 404 in 12ms
POST /api/graphql 404 in 11ms Error in Browser Unhandled Runtime Error
Error: An error occurred when loading Admin Metadata
Call Stack
useKeystone
..\node_modules\.pnpm\@[email protected]_@pri_58e2e8f8c13e7b27abab6294bec5bf80\node_modules\@keystone-6\core\admin-ui\context\dist\keystone-6-core-admin-ui-context.esm.js (321:1)
HomePage
..\node_modules\.pnpm\@[email protected]_@pri_58e2e8f8c13e7b27abab6294bec5bf80\node_modules\@keystone-6\core\___internal-do-not-use-will-break-in-patch\admin-ui\pages\HomePage\dist\keystone-6-core-___internal-do-not-use-will-break-in-patch-admin-ui-pages-HomePage.esm.js (119:18) A reiteration of the above errors. If I kill the Error in Terminal Failed to proxy http://localhost:3001/admin AggregateError [ECONNREFUSED]:
at internalConnectMultiple (node:net:1139:18)
at afterConnectMultiple (node:net:1712:7)
at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17) {
code: 'ECONNREFUSED',
[errors]: [
Error: connect ECONNREFUSED ::1:3001
at createConnectionError (node:net:1675:14)
at afterConnectMultiple (node:net:1705:16)
at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17) {
errno: -4078,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '::1',
port: 3001
},
Error: connect ECONNREFUSED 127.0.0.1:3001
at createConnectionError (node:net:1675:14)
at afterConnectMultiple (node:net:1705:16)
at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17) {
errno: -4078,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 3001
}
]
}
AggregateError [ECONNREFUSED]:
at internalConnectMultiple (node:net:1139:18)
at afterConnectMultiple (node:net:1712:7)
at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17) {
code: 'ECONNREFUSED',
[errors]: [
Error: connect ECONNREFUSED ::1:3001
at createConnectionError (node:net:1675:14)
at afterConnectMultiple (node:net:1705:16)
at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17) {
errno: -4078,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '::1',
port: 3001
},
Error: connect ECONNREFUSED 127.0.0.1:3001
at createConnectionError (node:net:1675:14)
at afterConnectMultiple (node:net:1705:16)
at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17) {
errno: -4078,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 3001
}
]
} Build ErrorBuilding Next app via using on Windows ❯ pnpm keystone build --no-ui
✨ Generated GraphQL and Prisma schemas
Error: EPERM: operation not permitted, rename 'I:\vscode\Keystone-Next-Auth-AIO-Exammple\node_modules\.pnpm\@[email protected]_prisma_5380e86ae666e62231e39370a63254fc\node_modules\.prisma\client\query_engine-windows.dll.node.tmp20244' -> 'I:\vscode\Keystone-Next-Auth-AIO-Exammple\node_modules\.pnpm\@[email protected]_prisma_5380e86ae666e62231e39370a63254fc\node_modules\.prisma\client\query_engine-windows.dll.node'
at async Object.rename (node:internal/fs/promises:783:10)
at async overwriteFile (I:\vscode\Keystone-Next-Auth-AIO-Exammple\node_modules\.pnpm\@[email protected]_prisma_5380e86ae666e62231e39370a63254fc\node_modules\@prisma\client\generator-build\index.js:5269:5)
at async generateClient (I:\vscode\Keystone-Next-Auth-AIO-Exammple\node_modules\.pnpm\@[email protected]_prisma_5380e86ae666e62231e39370a63254fc\node_modules\@prisma\client\generator-build\index.js:10866:7)
at async LineStream.<anonymous> (I:\vscode\Keystone-Next-Auth-AIO-Exammple\node_modules\.pnpm\@[email protected]_prisma_5380e86ae666e62231e39370a63254fc\node_modules\@prisma\client\generator-build\index.js:5172:24) {
code: -32000,
data: {
stack: "Error: EPERM: operation not permitted, rename 'I:\\vscode\\Keystone-Next-Auth-AIO-Exammple\\node_modules\\.pnpm\\@[email protected]_prisma_5380e86ae666e62231e39370a63254fc\\node_modules\\.prisma\\client\\query_engine-windows.dll.node.tmp20244' -> 'I:\\vscode\\Keystone-Next-Auth-AIO-Exammple\\node_modules\\.pnpm\\@[email protected]_prisma_5380e86ae666e62231e39370a63254fc\\node_modules\\.prisma\\client\\query_engine-windows.dll.node'\n" +
' at async Object.rename (node:internal/fs/promises:783:10)\n' +
' at async overwriteFile (I:\\vscode\\Keystone-Next-Auth-AIO-Exammple\\node_modules\\.pnpm\\@[email protected]_prisma_5380e86ae666e62231e39370a63254fc\\node_modules\\@prisma\\client\\generator-build\\index.js:5269:5)\n' +
' at async generateClient (I:\\vscode\\Keystone-Next-Auth-AIO-Exammple\\node_modules\\.pnpm\\@[email protected]_prisma_5380e86ae666e62231e39370a63254fc\\node_modules\\@prisma\\client\\generator-build\\index.js:10866:7)\n' +
' at async LineStream.<anonymous> (I:\\vscode\\Keystone-Next-Auth-AIO-Exammple\\node_modules\\.pnpm\\@[email protected]_prisma_5380e86ae666e62231e39370a63254fc\\node_modules\\@prisma\\client\\generator-build\\index.js:5172:24)'
},
name: 'GeneratorError'
} This error does not occur when I downgrade to Turbo BuildI'm very new to turbo, but I figured If I run it for multi services for dev I'll try it out for build as well. This does create a successful build "scripts": {
"ks:build_no_ui": "keystone build",
"n:build": "next build",
"tbuild": "turbo ks:build_no_ui n:build"
} > pnpm keystone build --no-ui && pnpm next build
✨ Generated GraphQL and Prisma schemas
Assertion failed: process_title, file c:\ws\deps\uv\src\win\util.c, line 418
ELIFECYCLE Command failed with exit code 3221226505. Specs
Next 15I'd prefer that this template uses Next 15 (using --turbopack). Looking at this framework it seems possible, but my attempt at making both the Next App and Keystone UI work at the same time is a game of wack-a-mole. Even when I resolve dependencies. ConclusionI'll take any help in this effort, and hopefully it can be worked into the examples page of Keystone. Later I hope to integrate my Docker Files and Next Auth config for people who'd like to self host keystone with Next: KYPN |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 2 replies
-
have you looked at #9186 ? My attempt to unify keystone with the NextJs instead of having NextJs nested inside .keystone/admin folder. |
Beta Was this translation helpful? Give feedback.
-
Hey @wchorski - I just added a comment to the issue you logged over here regarding the errors running dev: borisno2/on-the-hill-drama-club#696 (comment). Currently, my project, and the only way to do with with Keystone, is setup two NextJS apps:
App 1 then proxies If you are running keystone admin UI on port 3001, your I have also started creating a cutdown template over here https://github.com/OpenSaasAU/o8u-starter |
Beta Was this translation helpful? Give feedback.
-
Very much appreciate the slim down version. For now I'm going to stick with Next 14 (for Frontend and CMS) as there are many other edge cases I've ran into that I'd rather not deal with right now. My project integrates Next Auth so my repo has diverged a bit from your example. The project runs Next with the KS Admin UI (cross site with Next Auth) and creates a self hosted build with Docker https://github.com/wchorski/Keystone-Next-Auth-AIO-Exammple Still, there are a few lingering questions Borisno2 Example Reposviewing o8u-starter or on-the-hill-drama-club I don't understand how you're to
I only see one My repo runs optimized production build for keystone?Is there anyway to edit the pnpm keystone build
pnpm next start .keystone/admin -p 3001 Error in browser
No error in console/terminal
Is there something I don't understand about this deployment? or is it even possible with keystone? DockerfileGoing off of creating an "optimized production build" if you check my Error in console on deploy
Browser Error
Custom Component Blocks Error on Node v22 (sometimes v21)NextJs error in browser when accessing
This error doesn't happen when running in prod (docker containers) I know this to be an issue with using custom component blocks. I attempted to upgrade Keystone blocks, but ran into more issues when trying to use I get an editor error trying new keystar/ui component blocksI attempted to use the new components to create blocks but encountered another, separate issue
Attempting to use node v22 in Docker buildsin Dockerfile when setting platform to
next-keystone-aio-cms | ✨ Starting Keystone
next-keystone-aio-cms | ✨ Applying any database migrations
next-keystone-aio-cms | prisma:warn Prisma failed to detect the libssl/openssl version to use, and may not work as expected. Defaulting to "openssl-1.1.x".
next-keystone-aio-cms | Please manually install OpenSSL and try installing Prisma again.
next-keystone-aio-cms | npm notice
next-keystone-aio-cms | npm notice New major version of npm available! 10.9.2 -> 11.2.0
next-keystone-aio-cms | npm notice Changelog: https://github.com/npm/cli/releases/tag/v11.2.0
next-keystone-aio-cms | npm notice To update run: npm install -g [email protected]
next-keystone-aio-cms | npm notice
next-keystone-aio-cms exited with code 0
next-keystone-aio-cms | ✨ Starting Keystone
next-keystone-aio-cms | ✨ Applying any database migrations
next-keystone-aio-cms | prisma:warn Prisma failed to detect the libssl/openssl version to use, and may not work as expected. Defaulting to "openssl-1.1.x".
next-keystone-aio-cms | Please manually install OpenSSL and try installing Prisma again.
next-keystone-aio-cms exited with code 0
next-keystone-aio-cms | ✨ Starting Keystone tsconfigI saw this issue #8406 hoping I could have keystone files support custom paths too. I tried adding a wishlist
It seems to me if I want to get all the features out of keystone (component blocks in rich text editor, tsconfig paths, no Next version conflicts) the best course of action is to keep each app as separate directories with they're own dependencies. Is this true? |
Beta Was this translation helpful? Give feedback.
-
KeystarProviderI attempted to fix the Component Block error
by wrapping "use client"
import { KeystarProvider } from "@keystar/ui/core"
import { ActionGroup, Item } from "@keystar/ui/action-group"
import { ActionButton } from "@keystar/ui/button"
import { Tooltip, TooltipTrigger } from "@keystar/ui/tooltip"
import { Text } from "@keystar/ui/typography"
import { trash2Icon } from "@keystar/ui/icon/icons/trash2Icon"
import { Icon } from "@keystar/ui/icon"
import { Divider, Flex } from "@keystar/ui/layout"
import { type PropsWithChildren } from "react"
import { alertOctagonIcon } from "@keystar/ui/icon/icons/alertOctagonIcon"
import { alertTriangleIcon } from "@keystar/ui/icon/icons/alertTriangleIcon"
import { checkCircle2Icon } from "@keystar/ui/icon/icons/checkCircle2Icon"
import { infoIcon } from "@keystar/ui/icon/icons/infoIcon"
import { css, tokenSchema } from "@keystar/ui/style"
import React from "react"
import { NotEditable } from "@keystone-6/fields-document/component-blocks"
const toneToIcon = {
caution: alertTriangleIcon,
critical: alertOctagonIcon,
info: infoIcon,
positive: checkCircle2Icon,
}
const toneToColor = {
caution: "caution",
critical: "critical",
info: "accent",
positive: "positive",
} as const
export function Callout({
children,
tone = "info",
...props
}: PropsWithChildren<{
tone?: "info" | "caution" | "critical" | "positive"
}>) {
let icon = toneToIcon[tone]
let color = toneToColor[tone]
return (
<div
{...props}
className={css({
borderRadius: tokenSchema.size.radius.regular,
background: "var(--bg)",
color: "var(--fg)",
display: "flex",
gap: "1em",
padding: "1em",
svg: {
flexShrink: 0,
fill: "none",
stroke: "currentColor",
height: 20,
width: 20,
},
})}
style={{
// @ts-expect-error
"--bg": tokenSchema.color.background[color],
"--fg": tokenSchema.color.foreground[color],
}}
>
<KeystarProvider>
<NotEditable>
<Icon src={icon} />
</NotEditable>
</KeystarProvider>
<div>{children}</div>
</div>
)
}
export function CalloutToolbar(props: {
onChange: (tone: keyof typeof toneToIcon) => void
tones: readonly { label: string; value: keyof typeof toneToIcon }[]
tone: keyof typeof toneToIcon
onRemove: () => void
}) {
return (
<Flex gap="regular" padding="regular">
<KeystarProvider>
<ActionGroup
selectionMode="single"
prominence="low"
density="compact"
buttonLabelBehavior="hide"
onAction={(key) => {
props.onChange(key as any)
}}
selectedKeys={[props.tone]}
items={props.tones}
>
{(item) => (
<Item key={item.value} textValue={item.label}>
<Icon src={toneToIcon[item.value]} />
<Text>{item.label}</Text>
</Item>
)}
</ActionGroup>
<Divider orientation="vertical" />
<TooltipTrigger>
<ActionButton
prominence="low"
onPress={() => {
props.onRemove()
}}
>
<Icon src={trash2Icon} />
</ActionButton>
<Tooltip tone="critical">
<Text>Remove</Text>
</Tooltip>
</TooltipTrigger>
</KeystarProvider>
</Flex>
)
} |
Beta Was this translation helpful? Give feedback.
-
@wchorski were you able to figure out this KeystarProvider problem? |
Beta Was this translation helpful? Give feedback.
Hey @wchorski - I just added a comment to the issue you logged over here regarding the errors running dev: borisno2/on-the-hill-drama-club#696 (comment).
Currently, my project, and the only way to do with with Keystone, is setup two NextJS apps:
App 1 then proxies
/admin
onto app 2 using NextJSrewrites
If you are running keystone admin UI on port 3001, your
KEYSTONE_URL
should behttp://localhost:3001
I have also started creating a cutdown template over here https://github.com/OpenSaasAU/o8u-starter