-
Data
-
{JSON.stringify(data, null, 2)}
-
User
-
{JSON.stringify(user, null, 2)}
+
+
+
+
+ bknd w/ Remix
+
+
+

+

+
+
+
+
+
Go to Admin ➝
+
+ {ctx.user ? (
+
+ Authenticated as {ctx.user.email}
+
+ ) : (
+
Login
+ )}
+
+
+
);
}
diff --git a/examples/remix/app/routes/admin.$.tsx b/examples/remix/app/routes/admin.$.tsx
index 5aaa847..77f6747 100644
--- a/examples/remix/app/routes/admin.$.tsx
+++ b/examples/remix/app/routes/admin.$.tsx
@@ -4,6 +4,7 @@ import "bknd/dist/styles.css";
export default adminPage({
config: {
basepath: "/admin",
- logo_return_path: "/../"
+ logo_return_path: "/../",
+ color_scheme: "system"
}
});
diff --git a/examples/remix/app/routes/api.$.ts b/examples/remix/app/routes/api.$.ts
index 3d1911e..d01a6de 100644
--- a/examples/remix/app/routes/api.$.ts
+++ b/examples/remix/app/routes/api.$.ts
@@ -1,76 +1,9 @@
-import { App } from "bknd";
-import { registerLocalMediaAdapter } from "bknd/adapter/node";
-import { serve } from "bknd/adapter/remix";
-import { boolean, em, entity, text } from "bknd/data";
-import { secureRandomString } from "bknd/utils";
+import { getApp } from "~/bknd";
-// since we're running in node, we can register the local media adapter
-registerLocalMediaAdapter();
-
-const schema = em({
- todos: entity("todos", {
- title: text(),
- done: boolean()
- })
-});
-
-// register your schema to get automatic type completion
-type Database = (typeof schema)["DB"];
-declare module "bknd/core" {
- interface DB extends Database {}
-}
-
-const handler = serve({
- // we can use any libsql config, and if omitted, uses in-memory
- connection: {
- url: "file:test.db"
- },
- // an initial config is only applied if the database is empty
- initialConfig: {
- data: schema.toJSON(),
- // we're enabling auth ...
- auth: {
- enabled: true,
- jwt: {
- issuer: "bknd-remix-example",
- secret: secureRandomString(64)
- }
- },
- // ... and media
- media: {
- enabled: true,
- adapter: {
- type: "local",
- config: {
- path: "./public"
- }
- }
- }
- },
- options: {
- // the seed option is only executed if the database was empty
- seed: async (ctx) => {
- await ctx.em.mutator("todos").insertMany([
- { title: "Learn bknd", done: true },
- { title: "Build something cool", done: false }
- ]);
- }
- },
- // here we can hook into the app lifecycle events ...
- beforeBuild: async (app) => {
- app.emgr.onEvent(
- App.Events.AppFirstBoot,
- async () => {
- // ... to create an initial user
- await app.module.auth.createUser({
- email: "ds@bknd.io",
- password: "12345678"
- });
- },
- "sync"
- );
- }
-});
+const handler = async (args: { request: Request }) => {
+ const app = await getApp(args);
+ return app.fetch(args.request);
+};
export const loader = handler;
export const action = handler;
diff --git a/examples/remix/app/tailwind.css b/examples/remix/app/tailwind.css
new file mode 100644
index 0000000..6f64770
--- /dev/null
+++ b/examples/remix/app/tailwind.css
@@ -0,0 +1,10 @@
+@import "tailwindcss";
+
+html,
+body {
+ @apply bg-white dark:bg-gray-950;
+
+ @media (prefers-color-scheme: dark) {
+ color-scheme: dark;
+ }
+}
diff --git a/examples/remix/package.json b/examples/remix/package.json
index 2901131..d375498 100644
--- a/examples/remix/package.json
+++ b/examples/remix/package.json
@@ -1,33 +1,35 @@
{
- "name": "remix",
- "private": true,
- "sideEffects": false,
- "type": "module",
- "scripts": {
- "build": "remix vite:build",
- "dev": "remix vite:dev",
- "start": "remix-serve ./build/server/index.js",
- "typecheck": "tsc"
- },
- "dependencies": {
- "@remix-run/node": "^2.15.2",
- "@remix-run/react": "^2.15.2",
- "@remix-run/serve": "^2.15.2",
- "bknd": "file:../../app",
- "isbot": "^5.1.18",
- "react": "file:../../node_modules/react",
- "react-dom": "file:../../node_modules/react-dom",
- "remix-utils": "^7.0.0"
- },
- "devDependencies": {
- "@remix-run/dev": "^2.15.2",
- "@types/react": "^18.2.20",
- "@types/react-dom": "^18.2.7",
- "typescript": "^5.1.6",
- "vite": "^5.1.0",
- "vite-tsconfig-paths": "^4.2.1"
- },
- "engines": {
- "node": ">=20.0.0"
- }
-}
\ No newline at end of file
+ "name": "remix",
+ "private": true,
+ "sideEffects": false,
+ "type": "module",
+ "scripts": {
+ "build": "remix vite:build",
+ "dev": "remix vite:dev",
+ "start": "remix-serve ./build/server/index.js",
+ "typecheck": "tsc"
+ },
+ "dependencies": {
+ "@remix-run/node": "^2.15.2",
+ "@remix-run/react": "^2.15.2",
+ "@remix-run/serve": "^2.15.2",
+ "bknd": "file:../../app",
+ "isbot": "^5.1.18",
+ "react": "file:../../node_modules/react",
+ "react-dom": "file:../../node_modules/react-dom",
+ "remix-utils": "^7.0.0"
+ },
+ "devDependencies": {
+ "@tailwindcss/vite": "^4.0.7",
+ "tailwindcss": "^4.0.7",
+ "@remix-run/dev": "^2.15.2",
+ "@types/react": "^18.2.20",
+ "@types/react-dom": "^18.2.7",
+ "typescript": "^5.1.6",
+ "vite": "^5.1.0",
+ "vite-tsconfig-paths": "^4.2.1"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+}
diff --git a/examples/remix/public/logo-dark.png b/examples/remix/public/logo-dark.png
new file mode 100644
index 0000000..b24c7ae
Binary files /dev/null and b/examples/remix/public/logo-dark.png differ
diff --git a/examples/remix/public/logo-light.png b/examples/remix/public/logo-light.png
new file mode 100644
index 0000000..4490ae7
Binary files /dev/null and b/examples/remix/public/logo-light.png differ
diff --git a/examples/remix/vite.config.ts b/examples/remix/vite.config.ts
index 3fa98cd..b5632d1 100644
--- a/examples/remix/vite.config.ts
+++ b/examples/remix/vite.config.ts
@@ -1,4 +1,5 @@
import { vitePlugin as remix } from "@remix-run/dev";
+import tailwindcss from "@tailwindcss/vite";
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";
@@ -10,6 +11,7 @@ declare module "@remix-run/node" {
export default defineConfig({
plugins: [
+ tailwindcss(),
remix({
future: {
v3_fetcherPersist: true,