Files
nuxt4/programing_guide.md
T
2026-05-03 07:26:12 +00:00

19 KiB

Programming Guide

Tento dokument sluzi ako prakticky sprievodca template-om. Pri kazdej casti popisuje:

  • co template poskytuje
  • ci sa dana cast musi pouzit
  • ako sa pouziva
  • kratky priklad
  • ako sa da rozsirit

Poznamka:

  • vsetko v tomto template je navrhnute tak, aby sa dalo pouzit postupne
  • projekt nemusis prijat ako jeden velky balik
  • niektore casti su povinne len technicky, nie architektonicky

Prehlad

Template poskytuje tieto hlavne casti:

  • Nuxt 4 aplikaciu
  • TypeScript
  • Nuxt UI ako predvolenu UI vrstvu
  • i18n pre sk a en
  • Pinia store-y
  • volitelnu auth kostru
  • API vrstvu pripravenu na OpenAPI
  • logger composable a plugin
  • globalne SCSS styly a tokeny
  • VS Code konfiguraciu
  • lint, format, typecheck a test skripty
  • Vitest test harness pre store-y, pluginy, middleware a locale konzistenciu

Nuxt 4 Aplikacia

Co poskytuje:

  • zakladnu strukturu Nuxt 4 projektu
  • app/ adresar pre pages, layouts, plugins, stores a composables
  • nuxt.config.ts pre centralnu konfiguraciu

Musi sa pouzit:

  • ano
  • je to jadro celeho template-u

Ako pouzit:

  • vytvaraj routy v app/pages
  • vytvaraj spolocne layouty v app/layouts
  • pridavaj runtime logiku cez app/plugins a app/composables

Priklad:

<!-- app/pages/about.vue -->
<template>
  <div>About page</div>
</template>

Moznosti rozsirenia:

  • pridat dalsie Nuxt moduly do nuxt.config.ts
  • doplnit server routes do server/routes
  • doplnit middleware, plugins a composables podla potrieb projektu

TypeScript

Co poskytuje:

  • typovanie pre komponenty, composables, stores a plugin injections
  • centralne rozsirene Nuxt typy v app/types

Musi sa pouzit:

  • prakticky ano
  • template je na TypeScripte postaveny

Ako pouzit:

  • zapisuj nove composables a utility v .ts
  • definuj domenove typy do app/types

Priklad:

export interface Customer {
  id: string
  name: string
}

Moznosti rozsirenia:

  • pridat dalsie domenove typy
  • rozsirit RouteMeta alebo NuxtApp injekcie
  • doplnit typy pre generovane OpenAPI klienty

Odporucanie:

  • pri rozsireni NuxtApp injekcii alebo aliasov udrzuj v synchronizacii aj vitest.config.ts, aby sa dali nove pluginy testovat mimo Nuxt runtime

Nuxt UI

Co poskytuje:

  • standardnu komponentovu vrstvu pre formularove a bezne aplikacne UI
  • komponenty ako UApp, UButton, UCard, UInput, USelect, UFormField, UAlert
  • integrovany color mode a konzistentne API komponentov

Musi sa pouzit:

  • nie
  • ale je to predvolena UI vrstva template-u

Ako pouzit:

  • v page alebo komponente pouzi U* komponenty priamo
  • nevytvaraj dalsiu vlastnu vrstvu zakladnych button/input/card komponentov, ak na to nie je silny dovod

Priklad:

<template>
  <UCard variant="soft">
    <template #header>
      <h2>Profil</h2>
    </template>

    <UFormField label="Meno">
      <UInput v-model="name" />
    </UFormField>

    <UButton>Ulozit</UButton>
  </UCard>
</template>

<script setup lang="ts">
const name = ref('')
</script>

Moznosti rozsirenia:

  • vytvarat vlastne feature komponenty nad Nuxt UI
  • doplnit komplexne custom komponenty, napriklad diagramy alebo editory
  • zmenit vzhlad cez app config, CSS a globalne styly

Odporucany pristup:

  • bezne app UI nech riesi Nuxt UI
  • specializovane vizualizacie nech riesia vlastne Vue komponenty alebo specializovane kniznice

i18n

Co poskytuje:

  • lokalizaciu pre sk a en
  • preklady v i18n/locales/sk.json a i18n/locales/en.json
  • default locale sk

Musi sa pouzit:

  • nie
  • ale je uz zapojene a pripravene

Ako pouzit:

  • texty zapisuj do locale JSON suborov
  • v komponente pouzi useI18n()

Priklad:

const { t } = useI18n()
const title = t('app.title')
{
  "app": {
    "title": "Moja aplikacia"
  }
}

Moznosti rozsirenia:

  • pridat dalsie jazyky do nuxt.config.ts
  • doplnit dalsie namespace v locale JSON suboroch
  • zaviest konvencie pre preklady podla modulov, napriklad users.list.title

Automaticke overenie:

  • template obsahuje test, ktory porovnava strukturu klucov v i18n/locales/sk.json a i18n/locales/en.json
  • pri pridani noveho textu ho dopln do oboch suborov, inak test zlyha

Pinia

Co poskytuje:

  • centralny stav aplikacie
  • pripraveny auth store v app/stores/auth.ts
  • pripraveny ui store v app/stores/ui.ts

Musi sa pouzit:

  • nie
  • ale je odporucany pre zdielany stav

Ako pouzit:

  • lokalny stav formulara drz v komponente
  • globalny alebo zdielany stav drz v store

Priklad auth store:

const authStore = useAuthStore()

if (authStore.isAuthenticated) {
  console.log(authStore.displayName)
}

Priklad ui store:

const uiStore = useUiStore()

uiStore.startLoading()

try {
  uiStore.pushNotification({
    title: 'Hotovo',
    message: 'Data boli ulozene.',
    tone: 'success'
  })
} finally {
  uiStore.stopLoading()
}

Moznosti rozsirenia:

  • pridat dalsie store-y, napriklad filters, settings, drafts
  • napojit ui store na globalne toasty alebo loading overlay
  • rozsirit auth store o session info alebo permission model

Automaticke overenie:

  • existuju unit testy pre auth aj ui store, takze zmeny v ich API alebo vypocitavanych hodnotach vies chytit skor, nez sa dostanu do UI

Autorizacia A Auth Kostra

Co poskytuje:

  • vendor-neutral auth vrstvu
  • useAuth() composable
  • auth plugin v app/plugins/auth.ts
  • globalny middleware v app/middleware/auth.global.ts
  • route meta typy public, requiresAuth, roles

Musi sa pouzit:

  • nie
  • auth je volitelna

Ako pouzit:

  • nastav mod cez .env
  • route ochran len tam, kde to dava zmysel

Dostupne mody:

  • disabled
  • mock
  • userinfo

Priklad .env:

NUXT_PUBLIC_AUTH_MODE=mock

Priklad v komponente:

const auth = useAuth()

await auth.ensureInitialized()

if (auth.isAuthenticated.value) {
  console.log(auth.user.value?.email)
}

Priklad ochrany route:

definePageMeta({
  requiresAuth: true
})

Priklad ochrany podla role:

definePageMeta({
  requiresAuth: true,
  roles: ['ADMIN']
})

Moznosti rozsirenia:

  • napojit userinfo mod na realny backend alebo oauth2-proxy endpoint
  • doplnit mapovanie backend user modelu
  • pridat jemnejsi access model typu permissions alebo hasAccess(user)
  • doplnit login alebo logout UI do layoutu

Automaticke overenie:

  • auth plugin ma testy pre disabled, mock a userinfo
  • middleware ma testy pre public, requiresAuth a roles
  • to znamena, ze zmeny v auth kostre vies overit bez browser manualu

API Vrstva

Co poskytuje:

  • centralnu API konfiguraciu v nuxt.config.ts
  • API plugin v app/plugins/api.client.ts
  • useApi() composable
  • wrapper vrstvu v api/wrappers

Musi sa pouzit:

  • nie
  • ale je to odporucany sposob volania backendu

Ako pouzit:

  • z komponentov volaj useApi()
  • konkretne HTTP detaily drz vo wrapperoch

Priklad:

const api = useApi()

const health = await api.example.getHealth()
const welcome = await api.example.getWelcome()

Zakladne env:

NUXT_PUBLIC_API_BASE_URL=/api
NUXT_PUBLIC_API_TIMEOUT_MS=10000

Moznosti rozsirenia:

  • pridat dalsie API wrappery do api/wrappers
  • rozdelit klientov podla domen, napriklad users, projects, reports
  • doplnit error handling, retry alebo auth headers

Odporucanie:

  • UI nema volat fetch napriamo, ak to nie je jednorazova drobnost
  • preferuj centralnu API vrstvu pre konzistenciu

Automaticke overenie:

  • ukazkovy wrapper api/wrappers/example.ts aj plugin app/plugins/api.client.ts maju Vitest testy
  • pri pridani dalsieho wrappera je dobry standard doplnit rovnaky test hned s implementaciou

OpenAPI Priprava

Co poskytuje:

  • openapi-spec pre specifikacie a generator configy
  • openapi-client pre generovanych klientov
  • openapi-ts.config.ts
  • skripty pnpm generate:api a pnpm generate:example-api

Musi sa pouzit:

  • nie
  • je to priprava pre projekty, kde FE alebo BE kontrakt existuje ako OpenAPI

Ako pouzit:

  1. vloz alebo nahrad OpenAPI specifikaciu v openapi-spec
  2. uprav openapi-ts.config.ts
  3. spusti generator
  4. napoj vysledok cez api/wrappers

Priklad:

pnpm generate:api

Moznosti rozsirenia:

  • generovat viac klientov pre viac backendov
  • verzovat alebo neverzovat generovany kod podla timovej dohody
  • doplnit wrappery, ktore skryju rozdiely medzi backendmi

Odporucanie:

  • negenerovany kod nech ostane v api/wrappers a app/composables
  • komponenty nech nevolaju generovany OpenAPI klient priamo
  • generator je Node-native, takze workflow funguje aj bez Javy

Logger

Co poskytuje:

  • jednoduchy logger plugin
  • useLogger() composable
  • dostupnost cez Nuxt inject

Musi sa pouzit:

  • nie

Ako pouzit:

const logger = useLogger()

logger.info('User opened page', { section: 'dashboard' })
logger.error('Save failed', { id: '123' })

Moznosti rozsirenia:

  • napojit logovanie na externe sluzby
  • doplnit odlisne spravanie pre dev a production
  • pridat korelacne ID alebo request context

Automaticke overenie:

  • logger plugin ma test na format vystupu
  • useLogger() ma test na spravne Nuxt inject spravanie

Testovanie A Overenie

Co sa overuje automaticky:

  • store-y
  • pluginy
  • middleware
  • API wrappery
  • i18n kluce

Zakladny verify workflow:

pnpm lint
pnpm typecheck
pnpm test:run
pnpm build

Cielene spustenie infrastructure testov template-u:

pnpm vitest run tests/auth.plugin.spec.ts tests/auth.middleware.spec.ts tests/i18n.locales.spec.ts tests/api.plugin.spec.ts tests/logger.plugin.spec.ts tests/use-logger.spec.ts

Poznamka:

  • testy pre pluginy a middleware pouzivaju vitest.config.ts, kde su nastavene aliasy ~, @, ~~ a @@
  • ak pridas nove runtime injekcie alebo novu rozsirenu Nuxt vrstvu, je dobre doplnit test este v tom istom PR

Globalne Styly A Tokeny

Co poskytuje:

  • app/assets/styles/ui.css
  • app/assets/styles/_tokens.scss
  • app/assets/styles/_theme.scss
  • app/assets/styles/_base.scss
  • app/assets/styles/main.scss

Musi sa pouzit:

  • ciastocne ano
  • stylova vrstva je sucast template-u, ale mozes ju zmensit alebo vymenit

Ako pouzit:

  • ui.css nechaj ako vstup pre tailwindcss a @nuxt/ui
  • layoutove a globalne upravy rob v _base.scss
  • Nuxt UI farby skus najprv nastavit v nuxt.config.ts cez appConfig.ui.colors
  • _theme.scss pouzi len na male override-y nad Nuxt UI tokenmi
  • zakladne app-level hodnoty drz v _tokens.scss

Priklad:

export default defineNuxtConfig({
  appConfig: {
    ui: {
      colors: {
        primary: 'blue',
        neutral: 'slate'
      }
    }
  }
})

Moznosti rozsirenia:

  • doplnit branding projektu
  • upravit typografiu, spacing a farby
  • v pripade potreby jemne prepisat Nuxt UI tokeny bez budovania vlastneho design systemu

Odporucany mentalny model:

  • Nuxt UI je zdroj pravdy pre komponentovy vizual
  • _tokens.scss drzi male spolocne hodnoty pre app shell
  • _theme.scss riesi rozdiel medzi light a dark vizualom
  • _base.scss riesi vlastne layout triedy a app-specific CSS

Co menit v ktorom subore

nuxt.config.ts

  • semanticke farby pre Nuxt UI ako prvy krok
  • ine Nuxt-level nastavenia

Priklad:

export default defineNuxtConfig({
  appConfig: {
    ui: {
      colors: {
        primary: 'blue',
        neutral: 'slate'
      }
    }
  }
})

app/assets/styles/ui.css

  • nechaj len import Nuxt UI vrstvy
  • tento subor nie je miesto na app-specific styling

Priklad:

@import "tailwindcss";
@import "@nuxt/ui";

app/assets/styles/_tokens.scss

  • radius
  • font family
  • layout max width

Priklad:

:root {
  --font-family-base: 'Segoe UI', sans-serif;
  --page-max-width: 1320px;
  --ui-radius: 1rem;
}

app/assets/styles/_theme.scss

  • jemne prepisy Nuxt UI CSS tokenov
  • light/dark rozdiely bez stavania vlastnej komponentovej kniznice

Priklad:

:root,
.light {
  --ui-primary: var(--ui-color-primary-600);
  --ui-bg: #f8fafc;
}

.dark {
  --ui-primary: var(--ui-color-primary-400);
  --ui-bg: #0b1220;
}

app/assets/styles/_base.scss

  • vlastne wrapper triedy
  • spacing a layout pre shell
  • app-specific utility a responzivne pravidla

Priklad:

.page-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.25rem;
}

Ako funguje light, dark a system tema

Template pouziva useColorMode() a prepinac v app/layouts/default.vue.

Pouzivane hodnoty:

  • light
  • dark
  • system

Priklad vlastneho prepinaca:

<script setup lang="ts">
const colorMode = useColorMode()

function cycleTheme() {
  colorMode.preference =
    colorMode.preference === 'light'
      ? 'dark'
      : colorMode.preference === 'dark'
        ? 'system'
        : 'light'
}
</script>

<template>
  <UButton @click="cycleTheme">
    Zmenit temu
  </UButton>
</template>

Kedy menit preference a kedy CSS premenne:

  • colorMode.preference meni aktivny mod
  • CSS premenne v _theme.scss menia, ako light a dark mod vyzera

Typicke scenare uprav

  1. Chces iny primary button color. Najprv skus appConfig.ui.colors v nuxt.config.ts, a ak chces presnejsi vysledok, dolad --ui-primary v _theme.scss.
  2. Chces tmavsi dark background a jemnejsie card borders. Uprav --ui-bg, --ui-bg-muted a --ui-border v _theme.scss.
  3. Chces vacsi radius pre buttony, inputs a cards. Zmen --ui-radius v _tokens.scss.
  4. Chces sirsi layout alebo iny spacing hero sekcie. Uprav _base.scss.

Priklady praktickych uprav

Zmena radiusu pre celu app:

:root {
  --ui-radius: 1rem;
}

Jemnejsi light mode:

:root,
.light {
  --ui-bg: #f8fafc;
  --ui-bg-muted: #f1f5f9;
  --ui-border: #dbe4ee;
}

Vyraznejsi dark mode:

.dark {
  --ui-bg: #0b1220;
  --ui-bg-muted: #111827;
  --ui-border: #1f2937;
  --ui-text: #e5eef9;
}

Silnejsia primarna farba v light mode a jemnejsia v dark mode:

:root {
  --ui-primary: var(--ui-color-primary-700);
}

.dark {
  --ui-primary: var(--ui-color-primary-400);
}

Docker Release Image

Co poskytuje:

Musi sa pouzit:

  • nie
  • ale je to odporucana cesta pre release a deploy

Ako pouzit:

  • buildni image cez docker build
  • spusti kontajner s namapovanym portom 3000
  • runtime premenne dodaj cez -e

Priklad:

docker build -t nuxt-workspace-template:latest .
docker run --rm -p 3000:3000 nuxt-workspace-template:latest

Priklad s runtime premennymi:

docker run --rm -p 3000:3000 `
  -e NUXT_PUBLIC_API_BASE_URL=https://api.example.com `
  -e NUXT_PUBLIC_AUTH_MODE=userinfo `
  nuxt-workspace-template:latest

Poznamky:

  • build stage pouziva node:24-bookworm-slim
  • runtime stage pouziva hardened gcr.io/distroless/nodejs24-debian12:nonroot
  • kontajner spusta .output/server/index.mjs
  • image je urceny pre release alebo deploy, nie pre hot-reload development

Layout

Co poskytuje:

  • spolocny shell aplikacie v app/layouts/default.vue
  • branding, prepinanie locale a prepinanie temy

Musi sa pouzit:

  • nie
  • ale je to predvoleny layout

Ako pouzit:

  • nechaj sem spolocne prvky aplikacie
  • stranky sa do neho renderuju cez <slot />

Priklad rozsirenia:

  • pridat navigation bar
  • pridat user menu
  • pridat globalne notifikacie alebo loading indikator

Demo Stranka

Co poskytuje:

  • ukazkovu domovsku stranku v app/pages/index.vue
  • priklad pouzitia i18n, loggera, Nuxt UI a theme switchingu

Musi sa pouzit:

  • nie
  • je to iba demo start point

Ako pouzit:

  • nahrad ju vlastnym dashboardom alebo landing page

Moznosti rozsirenia:

  • prerobit na prehlad systemu
  • pouzit ju ako interny style guide pre tim
  • rozdelit ukazky do samostatnych routes

VS Code

Co poskytuje:

  • .vscode konfiguraciu

Musi sa pouzit:

  • nie
  • ale je to odporucany editorovy setup pre konzistentny workflow

Ako pouzit:

  • otvor repo vo VS Code
  • spusti pnpm dev

Moznosti rozsirenia:

  • pridat dalsie VS Code extensions
  • upravit Node verziu na hoste
  • pridat lokalne helper sluzby podla potrieb projektu

Kvalita Kodu

Co poskytuje:

  • ESLint
  • Prettier
  • Typecheck
  • Vitest

Musi sa pouzit:

  • technicky nie
  • prakticky ano, ak chces udrzatelny projekt

Ako pouzit:

pnpm lint
pnpm typecheck
pnpm test:run
pnpm format

Moznosti rozsirenia:

  • doplnit unit testy
  • doplnit component testy
  • zapojit CI pipeline
  • pridat pre-commit hooks

Runtime Config

Co poskytuje:

  • centralne public config hodnoty v nuxt.config.ts
  • API a auth env premenne

Musi sa pouzit:

  • nie
  • ale je to odporucany sposob konfiguracie

Ako pouzit:

Priklad .env:

NUXT_PUBLIC_API_BASE_URL=/api
NUXT_PUBLIC_API_TIMEOUT_MS=10000
NUXT_PUBLIC_AUTH_MODE=disabled
NUXT_PUBLIC_AUTH_USERINFO_URL=/api/auth/me

Prakticky start:

  1. skopiruj .env.example do .env
  2. nastav NUXT_PUBLIC_API_BASE_URL
  3. rozhodni NUXT_PUBLIC_AUTH_MODE
  4. ak budes pouzivat userinfo, dopln aj login, logout a userinfo URL

Poznamka:

  • public runtime config patri do .env, nie natvrdo do komponentov

Moznosti rozsirenia:

  • pridat dalsie public a private env premenne
  • rozdelit config podla modulov
  • doplnit feature flags

Co Je Povinny Zaklad A Co Je Volitelne

Povinny zaklad:

  • Nuxt 4
  • TypeScript
  • zakladna adresarova struktura
  • nuxt.config.ts

Silno odporucane, ale volitelne:

  • Nuxt UI
  • i18n
  • Pinia
  • API vrstva
  • logger
  • globalne styly

Volitelne casti:

  • auth kostra
  • OpenAPI generator workflow
  • lokalny host workflow nad VS Code
  • demo stranka v aktualnej podobe

Odporucany Sposob Pouzitia Template-u

Ak chces z template-u spravit realny projekt, odporucany postup je:

  1. uprav branding, title a preklady
  2. rozhodni, ci pouzijes auth a v akom mode
  3. nastav API base URL a priprav prve wrappery
  4. ak mate OpenAPI kontrakt, nahraj specifikaciu a nastav generator
  5. zacni stavat stranky priamo nad Nuxt UI komponentmi
  6. zdielany stav presuvaj do Pinia store-ov
  7. pred odovzdanim pravidelne pustaj lint, typecheck a testy

Ako spravit prvy krok prakticky:

  • v package.json zmen name
  • v nuxt.config.ts uprav app.head.title, titleTemplate a description
  • v i18n/locales/sk.json a i18n/locales/en.json prepis demo texty
  • v app/pages/index.vue nahrad ukazkovu domovsku stranku vlastnym obsahom
  • v nuxt.config.ts, app/assets/styles/_tokens.scss, _theme.scss a _base.scss dolad semanticke farby, spacing a globalny vizual

Odporucany Sposob Rozsirovania

Najrozumnejsie miesto pre rozsirovanie podla typu zmeny:

  • nova route alebo obrazovka: app/pages
  • nova zdielana UI cast alebo zlozitejsi widget: app/components
  • nova zdielana logika: app/composables
  • novy globalny stav: app/stores
  • nove backend volania: api/wrappers
  • nova OpenAPI specifikacia: openapi-spec
  • nova plugin integracia: app/plugins
  • nove typy: app/types

Priklad rozsirania o novu feature:

  1. vytvor app/pages/users/list.vue
  2. pridaj api/wrappers/users.ts
  3. dopln typy do app/types/api.ts alebo pouzi generovany klient
  4. ak treba, pridaj app/stores/users.ts
  5. texty dopln do i18n/locales/*.json

Zaverecne Odporucanie

Tento template nie je monolit, ktory musis pouzit cely. Je to pripraveny zaklad, z ktoreho si mozes zobrat:

  • len Nuxt UI a i18n
  • len API a OpenAPI workflow
  • len auth skeleton
  • alebo kompletne vsetky vrstvy spolu

Najlepsie funguje vtedy, ked:

  • bezne UI stavas priamo s Nuxt UI
  • backend komunikaciu drzis v wrapperoch
  • zdielany stav davas do Pinie
  • auth zapinas len tam, kde ho naozaj potrebujes