refactor(docs): note for NuxtLink usage, added geist font in example, minor cleanups

This commit is contained in:
2026-03-14 22:57:05 +05:30
parent 7751ee5db8
commit 06f9c3ee15
6 changed files with 57 additions and 20 deletions

View File

@@ -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.

View File

@@ -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);
}

View File

@@ -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">&amp;</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>

View File

@@ -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">&amp;</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:

View File

@@ -54,5 +54,6 @@ export default {
adminOptions: {
adminBasepath: "/admin",
assetsPath: "/admin/",
logoReturnPath: "../..",
},
} satisfies NuxtBkndConfig;

View File

@@ -8,4 +8,5 @@ export default defineNuxtConfig({
title: "Nuxt 🤝 Bknd.io",
},
},
css: ["assets/css/main.css"],
});