# Nuxt Workspace Template Nuxt 4 template pre lokalny vyvoj vo VS Code na hoste. Repozitar obsahuje zakladnu aplikaciu s i18n, Nuxt UI, jednoduchym loggerom, volitelnou auth kostrou, OpenAPI-ready API vrstvou a predpripravenym workspace nastavenim pre lokalny vyvoj. Dalsia dokumentacia: - `quick_start.md`: rychly postup po vytvoreni projektu z template - `programing_guide.md`: podrobny prehlad toho, co template poskytuje, ako sa to pouziva a ako sa to da rozsirovat ## Co je pripravene - Nuxt `4.4.2` - TypeScript `5.9.3` - `pnpm` ako package manager - `@nuxtjs/i18n` s jazykmi `sk` a `en` - light, dark a system tema cez Nuxt color mode - klientsky logger dostupny cez composable - volitelna auth kostra s modmi `disabled`, `mock` a `userinfo` - OpenAPI-ready API vrstva s generator skriptmi a wrappermi - Nuxt UI ako predvolena komponentova vrstva - `.vscode` konfiguracia pre vyvoj vo VS Code - ESLint, Prettier a Vitest ## Pre koho je template Template je vhodny ako vychodiskovy bod pre: - dashboardy a interne aplikacie - portalove aplikacie - administracne rozhrania - mensie a stredne Nuxt projekty, kde chces zacat rychlo, ale nie od nuly ## Struktura projektu Najdolezitejsie casti repozitara: - `app/pages`: routovatelne stranky aplikacie - `app/layouts`: spolocny layout aplikacie - `app/components`: miesto pre vlastne feature alebo komplexne komponenty nad Nuxt UI - `app/composables`: zdielana klientska logika, napr. tema a logger - `app/plugins`: Nuxt pluginy dostupne v runtime - `tests`: Vitest testy pre store-y, pluginy, middleware a i18n konzistenciu - `app/assets/styles`: globalne SCSS styly, tokeny a tema - `i18n/locales`: preklady pre jednotlive jazyky - `.vscode`: odporucane rozsirrenia, settings a debug konfiguracia - `nuxt.config.ts`: hlavna konfiguracia Nuxtu, modulov, globalnych stylov a i18n - `vitest.config.ts`: Vitest aliasy pre `~`, `@`, `~~` a `@@`, aby sa dali testovat Nuxt subory mimo runtime ## Ako pouzit tento template ### 1. Vytvor projekt z template Pouzi tento repozitar ako zaklad a uprav si aspon: - nazov projektu v `package.json` - titulok, meta a popis v `nuxt.config.ts` - texty v `i18n/locales/sk.json` a `i18n/locales/en.json` - uvodnu stranku v `app/pages/index.vue` - vizualny styl v `app/assets/styles` ### 2. Nastav prostredie Skopiruj `.env.example` do `.env` a dopln vlastne hodnoty podla potreby. Priklady: ```bash cp .env.example .env ``` ```powershell Copy-Item .env.example .env ``` ## Spustenie projektu ### Lokalny vyvoj na hoste Pozadovane je: - Node.js `^22.12.0 || >=24` - `corepack` Spustenie: ```bash corepack enable pnpm install pnpm dev ``` Potom otvor `http://localhost:3000`. Poznamky: - pri prvom starte moze Nuxt v dev rezime buildit pomalsie - ak je port `3000` obsadeny, Nuxt pouzije iny port, typicky `3001` - po otvoreni stranky sa moze prvy Vite build spustit az na prvy request ### Produkcny Docker image Template obsahuje pripraveny: - [Dockerfile](/c:/Data/Development/MANET/prjtemplates/vue/Dockerfile) - [.dockerignore](/c:/Data/Development/MANET/prjtemplates/vue/.dockerignore) Build image: ```bash docker build -t nuxt-workspace-template:latest . ``` Spustenie kontajnera: ```bash docker run --rm -p 3000:3000 nuxt-workspace-template:latest ``` Kontajner spusti hotovy Nitro server z `.output/server/index.mjs` a aplikacia bude dostupna na `http://localhost:3000`. Ak potrebujes odovzdat runtime premenne: ```powershell 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: - image je urceny pre release a deploy, nie pre hot-reload vyvoj - build stage pouziva `pnpm install --frozen-lockfile` a `pnpm build` - runtime stage pouziva hardened distroless Node 24 image a publikuje port `3000` - runtime image neobsahuje shell ani balast navyse, co pomaha znizit attack surface ## Zakladne skripty - `pnpm dev`: spusti vyvojovy server - `pnpm build`: vytvori produkcny build - `pnpm preview`: spusti preview produkcneho buildu - `pnpm generate:api`: spusti pripraveny OpenAPI codegen workflow - `pnpm generate:example-api`: vygeneruje ukazkoveho klienta do `openapi-client/example` cez `@hey-api/openapi-ts` - `pnpm lint`: spusti ESLint - `pnpm lint:fix`: opravi cast lint problemov automaticky - `pnpm typecheck`: spusti Nuxt typecheck - `pnpm test`: spusti Vitest v beznom rezime - `pnpm test:run`: spusti Vitest jednorazovo - `pnpm format`: skontroluje formatovanie cez Prettier - `pnpm format:fix`: naformatuje subory cez Prettier ## Automaticke Overenie Template ma pripraveny automaticky test coverage pre najdolezitejsie stavebne casti: - store-y `auth` a `ui` - auth plugin pre mody `disabled`, `mock` a `userinfo` - auth middleware pre `public`, `requiresAuth` a `roles` - API wrapper a API plugin - logger plugin a `useLogger()` - konzistenciu i18n klucov medzi `sk` a `en` Odporucany minimalny verify postup pred vacsou zmenou: ```bash pnpm lint pnpm typecheck pnpm test:run pnpm build ``` Ak chces spustit len novejsie infrastrukturalne testy template-u: ```bash 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 ``` ## Ako v tomto template vyvijat ### Kde upravovat stranky Kazdy subor v `app/pages` reprezentuje route. Priklad: - `app/pages/index.vue`: domovska stranka `/` Ak chces pridat novu stranku, vytvor novy `.vue` subor v `app/pages`. ### Kde upravovat spolocny layout Hlavny layout aplikacie je v: - `app/layouts/default.vue` Tu sa nachadza spolocna hlavicka, prepinac jazyka a prepinac temy. Vsetky stranky renderovane cez `NuxtPage` sa zobrazia v tomto layoute. Layout je postaveny na Nuxt UI komponentoch, najma `UBadge` a `USelect`. Korektne obalenie aplikacie cez `UApp` je v `app/app.vue`. ### Kde upravovat preklady Preklady su v: - `i18n/locales/sk.json` - `i18n/locales/en.json` Projekt pouziva `@nuxtjs/i18n` s jazykmi: - `sk` ako default - `en` ako druhy jazyk Ak pridas novy text do komponentu, dopln ho do oboch JSON suborov. ### Kde upravovat temu a vizual Globalne styly su nacitane cez `nuxt.config.ts` z: - `app/assets/styles/ui.css` - `app/assets/styles/main.scss` Subory stylov: - `app/assets/styles/ui.css`: nacitanie Tailwind CSS a Nuxt UI vrstvy - `app/assets/styles/_tokens.scss`: lahke app-level tokeny, napr. font, radius a layout rozmery - `app/assets/styles/_theme.scss`: volitelne theme override-y nad Nuxt UI tokenmi - `app/assets/styles/_base.scss`: globalne layout a app-specific styly Theme runtime logika je v: - Nuxt UI a `useColorMode()` Template rozlisuje: - preferenciu temy: `light`, `dark`, `system` - vyslednu aktivnu temu: `light` alebo `dark` Odporucany pristup je nemenit cely design system rucne, ale nechat Nuxt UI ako zdroj pravdy a upravovat len: - `nuxt.config.ts` cez `appConfig.ui.colors` ako prvy krok pre semanticke farby ako `primary` a `neutral` - `_theme.scss` pre male vizualne doladenia nad Nuxt UI tokenmi Prakticky to znamena: - v `ui.css` nechaj iba `@import "tailwindcss"` a `@import "@nuxt/ui"` - v `nuxt.config.ts` zacni semantickymi farbami a inymi Nuxt nastaveniami - v `_tokens.scss` men spolocne hodnoty ako `--ui-radius`, font alebo layout sirku - v `_theme.scss` men light/dark rozdiely cez Nuxt UI CSS premenne - v `_base.scss` rob app-level layout a globalne utility pre vlastne bloky ako `.shell`, `.page-grid` a podobne ### Ako funguje prepnutie temy Runtime prepnutie temy je postavene na `useColorMode()` a prepinaci v `app/layouts/default.vue`. Aktualna preferencia moze byt: - `light` - `dark` - `system` Pouzitie v komponente: ```ts const colorMode = useColorMode() colorMode.preference = 'dark' ``` Ak chces spravit vlastne tlacidlo na prepnutie temy: ```vue ``` ### Ako menit vizual bez vlastneho design systemu Najcastejsie scenare: - chces inu primarnu farbu buttonov a aktivnych prvkov: najprv skus `appConfig.ui.colors` v `nuxt.config.ts` - chces jemnejsie texty, tmavsie pozadie alebo iny border v dark mode: zmen Nuxt UI CSS premenne v `_theme.scss` - chces iny radius alebo sirsu app shell: zmen hodnoty v `_tokens.scss` - chces iny layout alebo spacing vlastnych blokov: uprav `_base.scss` Priklad zmeny radiusu a layoutu: ```scss :root { --ui-radius: 1rem; --page-max-width: 1320px; } ``` Priklad jemneho doladenia backgroundu a borderov: ```scss :root, .light { --ui-bg: #f8fafc; --ui-bg-muted: #f1f5f9; --ui-border: #dbe4ee; } .dark { --ui-bg: #0b1220; --ui-bg-muted: #111827; --ui-border: #1f2937; } ``` Priklad zmeny intenzity primarnej farby medzi light a dark modom: ```scss :root { --ui-primary: var(--ui-color-primary-600); } .dark { --ui-primary: var(--ui-color-primary-400); } ``` To je vhodne hlavne vtedy, ked chces nechat Nuxt UI komponenty a ich logiku bez zmeny, ale potrebujes jemne upravit kontrast alebo ton farby. ### Priklad konfiguracie v tomto template Aktualny template drzi semanticke farby v `nuxt.config.ts`: ```ts export default defineNuxtConfig({ appConfig: { ui: { colors: { primary: 'blue', neutral: 'slate' } } } }) ``` Tento zapis hovori Nuxt UI, aku paletu ma ma preferovat pre: - `color="primary"` - `color="neutral"` - utility ako `text-primary`, `bg-primary`, `text-muted`, `bg-default` a podobne Ak by si pri konkretnej verzii Nuxt UI potreboval jemnejsiu kontrolu nad realnym vysledkom, najspolahlivejsia cesta je doplnit CSS tokeny v `_theme.scss`, napr. `--ui-primary`, `--ui-bg` alebo `--ui-border`. ### Kde upravovat komponenty Template pouziva standardne Nuxt UI komponenty ako predvolenu UI vrstvu. Najcastejsie pouzite v template: - `UButton` - `UCard` - `UInput` - `USelect` - `UFormField` - `UAlert` - `UBadge` Pouzitie v komponente: ```vue Ulozit ``` Ak budes chciet rozsirit UI o vlastne komplexne komponenty, odporucany postup je skladat ich nad Nuxt UI, nie vytvarat paralelnu mini kniznicu zakladnych button/input/card komponentov. ### Kde upravovat logger Logger je pripraveny ako Nuxt plugin a composable: - `app/plugins/logger.ts` - `app/composables/useLogger.ts` Pouzitie v komponente: ```ts const logger = useLogger() logger.info('Akcia vykonana', { section: 'home' }) ``` Logy z klienta idu do konzoly prehliadaca. Logger ma aj automaticke testy, ktore overuju prefix, timestamp a spravanie s payloadom aj bez neho. ### Kde upravovat API a OpenAPI kontrakt Zaklad API vrstvy je v: - `app/plugins/api.client.ts` - `app/composables/useApi.ts` - `app/types/api.ts` - `api/wrappers` OpenAPI priprava je v: - `openapi-spec` - `openapi-client` - `openapi-ts.config.ts` Template funguje aj bez generovaneho klienta. Predvoleny wrapper `api/wrappers/example.ts` pouziva bezny `fetch` styl cez `$fetch`, ale ma rovnaky tvar ako vrstva, ktoru vies neskor napojit na vygenerovany OpenAPI client. API plugin a ukazkovy wrapper maju samostatne Vitest testy, takze zmeny v `runtimeConfig` alebo wrapper rozhrani vies zachytit automaticky. Pouzitie v stranke alebo komponente: ```ts const api = useApi() const health = await api.example.getHealth() const welcome = await api.example.getWelcome() ``` Odporucany vzor: - komponent alebo page vola `useApi()` - `useApi()` vracia klientov injectnutych z `app/plugins/api.client.ts` - konkretne HTTP volania alebo OpenAPI klient je schovany vo `api/wrappers` Tymto sposobom ostane UI oddelene od detailov backend komunikacie. Zakladne env pre API: - `NUXT_PUBLIC_API_BASE_URL` - `NUXT_PUBLIC_API_TIMEOUT_MS` Zakladny generator prikaz: ```bash pnpm generate:api ``` Odporucany postup: 1. nahrad `openapi-spec/example-api.yaml` vlastnou specifikaciou 2. uprav `openapi-ts.config.ts` 3. spusti `pnpm generate:api` 4. napoj vygenerovaneho klienta cez `api/wrappers` Ak uz mas backend kontrakt cez OpenAPI, odporucany sposob integracie je: 1. pridaj alebo aktualizuj `.yaml` specifikaciu v `openapi-spec` 2. vygeneruj klienta do `openapi-client` 3. v `api/wrappers` vytvor tenku vrstvu, ktora premapuje volania na domenove funkcie 4. z komponentov volaj iba `useApi()`, nie vygenerovany klient priamo Poznamka ku gitu: - obsah `openapi-client` je v template ignorovany, pretoze ide o generovane subory - v gite ostava len `openapi-client/README.md`, aby bolo jasne, na co adresar sluzi - ak bude tvoj tim chciet verzovat aj generovanych klientov, uprav `.gitignore` ### Kde upravovat autorizaciu Auth vrstva je zamerne volitelna. Ak ju projekt nepotrebuje, ostava vypnuta. Zakladne casti su v: - `app/plugins/auth.ts` - `app/composables/useAuth.ts` - `app/middleware/auth.global.ts` - `app/stores/auth.ts` - `app/types/auth.ts` Rezim auth sa nastavuje cez `.env`: - `NUXT_PUBLIC_AUTH_MODE=disabled`: auth je vypnuta a middleware nic nevynucuje - `NUXT_PUBLIC_AUTH_MODE=mock`: lokalny vyvoj s mock userom - `NUXT_PUBLIC_AUTH_MODE=userinfo`: nacitanie usera z endpointu `NUXT_PUBLIC_AUTH_USERINFO_URL` Pouzitie v komponente: ```ts const auth = useAuth() await auth.ensureInitialized() if (auth.isAuthenticated.value) { console.log(auth.user.value?.email) } ``` Pouzitie cez store: ```ts const authStore = useAuthStore() if (authStore.hasRole('ADMIN')) { // zobraz admin cast rozhrania } ``` Ak chces ochranit konkretnu stranku, pouzi route meta: ```ts definePageMeta({ requiresAuth: true }) ``` Alebo s rolami: ```ts definePageMeta({ requiresAuth: true, roles: ['ADMIN'] }) ``` Bezny scenar: - pocas lokalneho vyvoja nastav `NUXT_PUBLIC_AUTH_MODE=mock` - pre projekt bez prihlasenia nechaj `NUXT_PUBLIC_AUTH_MODE=disabled` - pre realne SSO alebo proxy endpoint pouzi `NUXT_PUBLIC_AUTH_MODE=userinfo` Auth middleware sa spusta globalne, ale zasahuje len na routach s `requiresAuth` alebo `roles`. ### Kde upravovat globalny stav cez Pinia Pinia sa hodi na stav, ktory je zdielany vo viacerych castiach aplikacie. Pripravene store-y: - `app/stores/auth.ts`: user, role, session stav - `app/stores/ui.ts`: loading a notifikacie Pouzitie `ui` store: ```ts const uiStore = useUiStore() uiStore.startLoading() try { uiStore.pushNotification({ title: 'Ulozene', message: 'Zmena bola uspesne ulozena.', tone: 'success' }) } finally { uiStore.stopLoading() } ``` Pouzitie `auth` store: ```ts const authStore = useAuthStore() const userName = authStore.displayName const isLoggedIn = authStore.isAuthenticated ``` Odporucanie: - lokalny stav formulára nechaj v komponente - zdielany stav typu user, loading, notifikacie alebo filtre dava zmysel drzat v store ### Ako pouzit Nuxt UI v tomto template Nuxt UI je zapojene ako Nuxt modul a je predvolenou UI vrstvou template. Zakladne pouzitie: 1. do page alebo komponentu pouzi `U*` komponenty priamo 2. nebuduj dalsiu vrstvu `BaseButton`, `BaseInput`, `BaseCard`, ak na to nie je silny dovod 3. vlastne komplikovane komponenty, napriklad diagramy alebo specialne editory, stavaj ako bezne Vue komponenty a Nuxt UI pouzi na ich okolie, toolbar, formulare a akcie Priklad: ```vue ``` ### Kde upravovat hlavnu konfiguraciu Hlavne nastavenia su v: - `nuxt.config.ts` Tu upravis napr.: - globalne CSS - Nuxt moduly - title a meta tagy - i18n konfiguraciu - devtools spravanie ## Odporucany workflow Pri beznej praci sa osvedci tento postup: 1. Spusti `pnpm dev`. 2. Otvor aplikaciu v prehliadaci. 3. Men stranky v `app/pages`, layout v `app/layouts` a texty v `i18n/locales`. 4. Priebežne kontroluj typy a lint: ```bash pnpm typecheck pnpm lint ``` 5. Pred odovzdanim alebo commitom over: ```bash pnpm format pnpm test:run pnpm build ``` ## VS Code Repozitar obsahuje: - `.vscode/settings.json`: workspace nastavenia - `.vscode/extensions.json`: odporucane rozsirrenia - `.vscode/launch.json`: jednoduche spustenie `pnpm dev` z VS Code Predinstalovane a odporucane rozsirrenia su zamerane najma na: - Vue a TypeScript - ESLint a Prettier - i18n preklady - Vitest ## Poznamky k dev rezimu - `pnpm install` spusta `postinstall`, ktory vola `nuxt prepare` - OpenAPI codegen ide cez `@hey-api/openapi-ts`, takze netreba Javu - prvy start po cistom install moze byt pomalsi - prvy Vite build sa moze spustit az pri prvom otvoreni stranky - ak sa objavi problem s viacerymi servermi, ukonci beziace Node alebo Nuxt procesy vo svojom terminali alebo cez Spravcu uloh a spusti iba jeden `pnpm dev` ## Co typicky zmenit ako prve Po vytvoreni noveho projektu z template sa obvykle meni: - branding a texty v prekladoch - titulky a meta udaje - farby, spacing a tokeny v stylech - obsah `app/pages/index.vue` - pouzitie a konfiguracia Nuxt UI komponentov podla potrieb projektu - vlastne feature komponenty v `app/components` - doplnenie dalsich stranok, API endpointov a testov