mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-15 20:17:22 +00:00
refactor(docs): note for NuxtLink usage, added geist font in example, minor cleanups
This commit is contained in:
@@ -189,7 +189,7 @@ export default defineEventHandler(async (event) => {
|
||||
```
|
||||
|
||||
<Callout type="warning">
|
||||
This can't be done in the `/server/api` directory as it will collide with the API endpoints created by the middleware. We will use [defineEventHandler](https://nuxt.com/docs/4.x/directory-structure/server) in the [/server/routes](https://nuxt.com/docs/4.x/directory-structure/server) directory to create endpoints and use them in conjunction with composables to access the API safely.
|
||||
This can't be done in the `server/api` directory as it will collide with the API endpoints created by the middleware. We will use [defineEventHandler](https://nuxt.com/docs/4.x/directory-structure/server) in the [server/routes](https://nuxt.com/docs/4.x/directory-structure/server) directory to create endpoints and use them in conjunction with composables to access the API safely.
|
||||
</Callout>
|
||||
|
||||
|
||||
@@ -385,4 +385,18 @@ onMounted(() => {
|
||||
</template>
|
||||
```
|
||||
|
||||
## Important Note
|
||||
|
||||
Use `external` attribute on Nuxt links, anytime you are traversing to an external route (like `/api/*` which are handled by bknd's middleware) to prevent vue router from intercepting the link.
|
||||
|
||||
```vue
|
||||
<NuxtLink external href="/admin">
|
||||
Admin
|
||||
</NuxtLink>
|
||||
```
|
||||
|
||||
<Callout type="error">
|
||||
If you don't use the `external` attribute, vue router will intercept the link and try to navigate to it, which will fail and result in a 404 error.
|
||||
</Callout>
|
||||
|
||||
Check the [Nuxt repository example](https://github.com/bknd-io/bknd/tree/main/examples/nuxt) for more implementation details.
|
||||
@@ -1,9 +1,15 @@
|
||||
@import "tailwindcss";
|
||||
@import url("https://fonts.googleapis.com/css2?family=Geist+Mono:wght@100..900&display=swap");
|
||||
|
||||
.geist-mono-100 {
|
||||
font-optical-sizing: auto;
|
||||
font-weight: 100;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
:root {
|
||||
--background: #ffffff;
|
||||
--foreground: #171717;
|
||||
font-weight: 400;
|
||||
font-family: "Geist Mono", monospace;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
@@ -14,11 +20,14 @@
|
||||
}
|
||||
|
||||
@theme {
|
||||
--font-sans: var(--font-geist-sans);
|
||||
--font-mono: var(--font-geist-mono);
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
}
|
||||
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
background-color: var(--background);
|
||||
color: var(--foreground);
|
||||
font-family: var(--font-geist-mono-100);
|
||||
}
|
||||
@@ -21,15 +21,15 @@ async function handleSubmit(event: Event) {
|
||||
<div v-if="todos !== undefined"
|
||||
class="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20">
|
||||
<main class="flex flex-col gap-8 row-start-2 items-center sm:items-start">
|
||||
<div class="flex flex-row items-center ">
|
||||
<img class="dark:invert size-24" src="/nuxt.svg" alt="Nuxt logo" />
|
||||
<div class="flex flex-row items-center justify-evenly min-w-full">
|
||||
<img class="size-24" src="/nuxt.svg" alt="Nuxt logo" />
|
||||
<div class="ml-3.5 mr-2 font-mono opacity-70">&</div>
|
||||
<img class="dark:invert" src="/bknd.svg" alt="bknd logo" width="183" height="59" />
|
||||
</div>
|
||||
|
||||
<List :items="['Get started with a full backend.', 'Focus on what matters instead of repetition.']" />
|
||||
|
||||
<div class="flex flex-col border border-foreground/15 w-full py-4 px-5 gap-2">
|
||||
<div class="flex flex-col border border-black/15 dark:border-white/15 w-full py-4 px-5 gap-2">
|
||||
<h2 class="font-mono mb-1 opacity-70"><code>What's next?</code></h2>
|
||||
<div class="flex flex-col w-full gap-2">
|
||||
<div v-if="todos.total > todos.limit"
|
||||
@@ -40,7 +40,10 @@ async function handleSubmit(event: Event) {
|
||||
<div class="flex flex-col gap-3">
|
||||
<div v-for="todo in todos.todos" :key="String(todo.id)" class="flex flex-row">
|
||||
<div class="flex flex-row flex-grow items-center gap-3 ml-1">
|
||||
<input type="checkbox" class="flex-shrink-0 cursor-pointer" :checked="!!todo.done"
|
||||
<input
|
||||
type="checkbox"
|
||||
class="flex-shrink-0 cursor-pointer"
|
||||
:checked="Boolean(todo.done)"
|
||||
@change="() => { toggleTodo(todo); refresh() }" />
|
||||
<div class="text-foreground/90 leading-none">{{ todo.title }}</div>
|
||||
</div>
|
||||
@@ -52,8 +55,11 @@ async function handleSubmit(event: Event) {
|
||||
</div>
|
||||
|
||||
<form class="flex flex-row w-full gap-3 mt-2" :key="todos.todos.map(t => t.id).join()" @submit="handleSubmit">
|
||||
<input type="text" name="title" placeholder="New todo"
|
||||
class="py-2 px-4 flex flex-grow rounded-sm bg-foreground/10 focus:bg-foreground/20 transition-colors outline-none" />
|
||||
<input
|
||||
type="text"
|
||||
name="title"
|
||||
placeholder="New todo"
|
||||
class="py-2 px-4 flex flex-grow rounded-sm bg-black/5 focus:bg-black/10 dark:bg-white/5 dark:focus:bg-white/10 transition-colors outline-none" />
|
||||
<button type="submit" class="cursor-pointer">Add</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -12,25 +12,31 @@ onMounted(() => {
|
||||
<div
|
||||
v-if="userStatus !== 'pending'"
|
||||
className="flex flex-col items-center justify-center min-h-screen p-8 pb-20 gap-16 sm:p-20"
|
||||
>
|
||||
>
|
||||
<main className="flex flex-col gap-8 row-start-2 justify-center items-center sm:items-start">
|
||||
<div class="flex flex-row items-center ">
|
||||
<img class="dark:invert size-24" src="/nuxt.svg" alt="Nuxt logo" />
|
||||
<div class="flex flex-row items-center justify-evenly min-w-full">
|
||||
<img class="size-24" src="/nuxt.svg" alt="Nuxt logo" />
|
||||
<div class="ml-3.5 mr-2 font-mono opacity-70">&</div>
|
||||
<img class="dark:invert" src="/bknd.svg" alt="bknd logo" width="183" height="59" />
|
||||
<img
|
||||
class="dark:invert"
|
||||
src="/bknd.svg"
|
||||
alt="bknd logo"
|
||||
width="183"
|
||||
height="59"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="data?.user">
|
||||
Logged in as {{ data.user.email }}.
|
||||
<a className="font-medium underline" href='/api/auth/logout'>
|
||||
<NuxtLink external className="font-medium underline" href='/api/auth/logout'>
|
||||
Logout
|
||||
</a>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
<div v-else className="flex flex-col gap-1">
|
||||
<p>
|
||||
Not logged in.
|
||||
<a className="font-medium underline" href="/admin/auth/login">
|
||||
<NuxtLink external className="font-medium underline" href="/admin/auth/login">
|
||||
Login
|
||||
</a>
|
||||
</NuxtLink>
|
||||
</p>
|
||||
<p className="text-xs opacity-50">
|
||||
Sign in with:
|
||||
|
||||
@@ -54,5 +54,6 @@ export default {
|
||||
adminOptions: {
|
||||
adminBasepath: "/admin",
|
||||
assetsPath: "/admin/",
|
||||
logoReturnPath: "../..",
|
||||
},
|
||||
} satisfies NuxtBkndConfig;
|
||||
|
||||
@@ -8,4 +8,5 @@ export default defineNuxtConfig({
|
||||
title: "Nuxt 🤝 Bknd.io",
|
||||
},
|
||||
},
|
||||
css: ["assets/css/main.css"],
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user