{{ post?.title }}
+{{ post?.content }}
+{{ post?.content }}
+Failed to load: {{ error.message }}
+ +
+
+
+
+```
+
+## Special Files
+
+| File | Purpose |
+|------|---------|
+| `app/app.vue` | Root component (optional with pages/) |
+| `app/app.config.ts` | Runtime app configuration |
+| `app/error.vue` | Custom error page |
+| `app/router.options.ts` | Vue Router configuration (Nuxt 4) |
+| `app/spa-loading-template.html` | SPA loading UI |
+| `nuxt.config.ts` | Build-time configuration |
+| `.nuxtignore` | Ignore files from Nuxt |
+| `.env` | Environment variables |
+
+## File Naming Conventions
+
+| Pattern | Meaning |
+|---------|---------|
+| `[param]` | Dynamic route parameter |
+| `[[param]]` | Optional parameter |
+| `[...slug]` | Catch-all route |
+| `(group)` | Route group (not in URL) |
+| `.client.vue` | Client-only component |
+| `.server.vue` | Server-only component |
+| `.global.ts` | Global middleware |
+
+
diff --git a/.claude/skills/nuxt/references/core-modules.md b/.claude/skills/nuxt/references/core-modules.md
new file mode 100644
index 0000000..dab3f95
--- /dev/null
+++ b/.claude/skills/nuxt/references/core-modules.md
@@ -0,0 +1,292 @@
+---
+name: nuxt-modules
+description: Creating and using Nuxt modules to extend framework functionality
+---
+
+# Nuxt Modules
+
+Modules extend Nuxt's core functionality. They run at build time and can add components, composables, plugins, and configuration.
+
+## Using Modules
+
+Install and add to `nuxt.config.ts`:
+
+```ts
+// nuxt.config.ts
+export default defineNuxtConfig({
+ modules: [
+ // npm package
+ '@nuxt/ui',
+ // Local module
+ './modules/my-module',
+ // Inline module
+ (options, nuxt) => {
+ console.log('Inline module')
+ },
+ // With options
+ ['@nuxt/image', { provider: 'cloudinary' }],
+ ],
+})
+```
+
+## Creating Modules
+
+### Basic Module
+
+```ts
+// modules/my-module.ts
+export default defineNuxtModule({
+ meta: {
+ name: 'my-module',
+ configKey: 'myModule',
+ },
+ defaults: {
+ enabled: true,
+ },
+ setup(options, nuxt) {
+ if (!options.enabled) return
+
+ console.log('My module is running!')
+ },
+})
+```
+
+### Adding Components
+
+```ts
+// modules/ui/index.ts
+import { addComponent, createResolver } from '@nuxt/kit'
+
+export default defineNuxtModule({
+ setup(options, nuxt) {
+ const { resolve } = createResolver(import.meta.url)
+
+ // Add single component
+ addComponent({
+ name: 'MyButton',
+ filePath: resolve('./runtime/components/MyButton.vue'),
+ })
+
+ // Add components directory
+ addComponentsDir({
+ path: resolve('./runtime/components'),
+ prefix: 'My',
+ })
+ },
+})
+```
+
+### Adding Composables
+
+```ts
+// modules/utils/index.ts
+import { addImports, createResolver } from '@nuxt/kit'
+
+export default defineNuxtModule({
+ setup() {
+ const { resolve } = createResolver(import.meta.url)
+
+ // Add auto-imported composable
+ addImports({
+ name: 'useMyUtil',
+ from: resolve('./runtime/composables/useMyUtil'),
+ })
+
+ // Add directory for auto-imports
+ addImportsDir(resolve('./runtime/composables'))
+ },
+})
+```
+
+### Adding Plugins
+
+```ts
+// modules/analytics/index.ts
+import { addPlugin, createResolver } from '@nuxt/kit'
+
+export default defineNuxtModule({
+ setup() {
+ const { resolve } = createResolver(import.meta.url)
+
+ addPlugin({
+ src: resolve('./runtime/plugin'),
+ mode: 'client', // 'client', 'server', or 'all'
+ })
+ },
+})
+```
+
+Plugin file:
+
+```ts
+// modules/analytics/runtime/plugin.ts
+export default defineNuxtPlugin((nuxtApp) => {
+ nuxtApp.hook('page:finish', () => {
+ console.log('Page loaded')
+ })
+})
+```
+
+### Adding Server Routes
+
+```ts
+// modules/api/index.ts
+import { addServerHandler, createResolver } from '@nuxt/kit'
+
+export default defineNuxtModule({
+ setup() {
+ const { resolve } = createResolver(import.meta.url)
+
+ addServerHandler({
+ route: '/api/my-endpoint',
+ handler: resolve('./runtime/server/api/my-endpoint'),
+ })
+ },
+})
+```
+
+### Extending Config
+
+```ts
+// modules/config/index.ts
+export default defineNuxtModule({
+ setup(options, nuxt) {
+ // Add CSS
+ nuxt.options.css.push('my-module/styles.css')
+
+ // Add runtime config
+ nuxt.options.runtimeConfig.public.myModule = {
+ apiUrl: options.apiUrl,
+ }
+
+ // Extend Vite config
+ nuxt.options.vite.optimizeDeps ||= {}
+ nuxt.options.vite.optimizeDeps.include ||= []
+ nuxt.options.vite.optimizeDeps.include.push('some-package')
+ },
+})
+```
+
+## Module Hooks
+
+```ts
+export default defineNuxtModule({
+ setup(options, nuxt) {
+ // Build-time hooks
+ nuxt.hook('modules:done', () => {
+ console.log('All modules loaded')
+ })
+
+ nuxt.hook('components:dirs', (dirs) => {
+ dirs.push({ path: '~/extra-components' })
+ })
+
+ nuxt.hook('pages:extend', (pages) => {
+ pages.push({
+ name: 'custom-page',
+ path: '/custom',
+ file: resolve('./runtime/pages/custom.vue'),
+ })
+ })
+
+ nuxt.hook('imports:extend', (imports) => {
+ imports.push({ name: 'myHelper', from: 'my-package' })
+ })
+ },
+})
+```
+
+## Module Options
+
+Type-safe options with defaults:
+
+```ts
+export interface ModuleOptions {
+ apiKey: string
+ enabled?: boolean
+ prefix?: string
+}
+
+export default defineNuxtModuleSomething went wrong: {{ error.message }}
+ +Loading chart...
+ +Modal content
+ +Loading...
+Loading...
+ +npm run build → npm run preview 실행swr: true는 TTL 없이 항상 캐시를 반환하고 매 요청마다 백그라운드 갱신합니다.{{ codeExample }}
+
+ 각 페이지에서 렌더링 방식의 차이를 확인해보세요.
+ +{{ page.description }}
+| + {{ col }} + | +
|---|
| + |
defineRouteRules({ ssr: false })로 서버 렌더링을 비활성화합니다.{{ codeExample }}
+
+ routeRules: { '/ssg': { prerender: true } }로 설정합니다.
+ nuxt generate 실행 시 /api/build-time을 딱 1회 호출하고,
+ 응답값을 HTML 안의 Nuxt payload에 직렬화합니다.
+ <script>window.__NUXT__ = { data: { time: "2026-..." } }</script>
+ nuxt generate 재실행 + 재배포가 필요합니다.
+ 자주 바뀌는 데이터라면 재배포 없이 자동 재생성하는 ISR(isr: N) 또는
+ SWR(swr: true)을 고려하세요.
+ npm run generate 후
+ .output/public/ssg/index.html을 열어 __NUXT__를 검색하면
+ 빌드 시 생성된 시간값이 HTML에 포함된 것을 볼 수 있습니다.
+ {{ codeExample }}
+
+ /api/time을 호출하고 HTML을 완성해 전달합니다.{{ codeExample }}
+
+ 로딩 중...
+ +