1. Error Tracking with Sentry
npm i @sentry/vue @sentry/node
// plugins/sentry.client.ts
import * as Sentry from '@sentry/vue'
export default defineNuxtPlugin((nuxtApp) => {
const config = useRuntimeConfig()
Sentry.init({
app: nuxtApp.vueApp,
dsn: config.public.sentryDsn,
environment: config.public.env,
integrations: [
Sentry.browserTracingIntegration({
router: useRouter(),
}),
Sentry.replayIntegration(),
],
tracesSampleRate: 0.1,
replaysSessionSampleRate: 0.05,
})
})
// server/plugins/sentry.ts
import * as Sentry from '@sentry/node'
export default defineNitroPlugin((nitro) => {
Sentry.init({
dsn: useRuntimeConfig().sentryDsn,
tracesSampleRate: 0.2,
})
nitro.hooks.hook('error', (error) => {
Sentry.captureException(error)
})
})
2. Structured Logging
// server/utils/logger.ts
import { consola, createConsola } from 'consola'
export const logger = createConsola({
level: process.env.NODE_ENV === 'production' ? 3 : 4,
formatOptions: {
date: true,
colors: process.env.NODE_ENV !== 'production',
},
})
// Sử dụng
logger.info('User logged in', { userId: user.id, ip: getRequestIP(event) })
logger.error('Payment failed', { orderId, error: err.message })
3. Health Checks
// server/api/health.get.ts
export default defineEventHandler(async () => {
const checks = {
status: 'ok',
timestamp: new Date().toISOString(),
uptime: process.uptime(),
memory: process.memoryUsage(),
checks: {} as Record<string, string>,
}
// Database check
try {
await db.execute(sql`SELECT 1`)
checks.checks.database = 'ok'
} catch {
checks.checks.database = 'error'
checks.status = 'degraded'
}
// Redis check
try {
await redis.ping()
checks.checks.redis = 'ok'
} catch {
checks.checks.redis = 'error'
checks.status = 'degraded'
}
return checks
})
4. Security Best Practices
// nuxt.config.ts
export default defineNuxtConfig({
security: {
headers: {
contentSecurityPolicy: {
'default-src': ["'self'"],
'script-src': ["'self'", "'nonce-{{nonce}}'"],
'style-src': ["'self'", "'unsafe-inline'"],
'img-src': ["'self'", 'data:', 'https:'],
},
xFrameOptions: 'DENY',
xContentTypeOptions: 'nosniff',
referrerPolicy: 'strict-origin-when-cross-origin',
},
corsHandler: {
origin: ['https://myapp.com'],
methods: ['GET', 'POST', 'PUT', 'DELETE'],
},
rateLimiter: {
tokensPerInterval: 100,
interval: 60000,
},
},
})
// server/middleware/csrf.ts
export default defineEventHandler((event) => {
if (['POST', 'PUT', 'DELETE'].includes(event.method)) {
const token = getHeader(event, 'x-csrf-token')
const sessionToken = getCookie(event, 'csrf-token')
if (!token || token !== sessionToken) {
throw createError({ statusCode: 403, message: 'Invalid CSRF token' })
}
}
})
5. Monorepo with pnpm Workspace
# pnpm-workspace.yaml
packages:
- 'apps/*'
- 'packages/*'
# Cấu trúc
monorepo/
├── pnpm-workspace.yaml
├── apps/
│ ├── web/ # Nuxt app chính
│ └── admin/ # Nuxt admin panel
├── packages/
│ ├── ui/ # Shared Vue components
│ ├── utils/ # Shared utilities
│ └── config/ # Shared configs (eslint, tsconfig)
// packages/ui/package.json
{
"name": "@myapp/ui",
"exports": {
".": "./src/index.ts",
"./components/*": "./src/components/*.vue"
}
}
// apps/web/package.json
{
"dependencies": {
"@myapp/ui": "workspace:*",
"@myapp/utils": "workspace:*"
}
}
6. Design System
<!-- packages/ui/src/components/BaseButton.vue -->
<script setup lang="ts">
interface Props {
variant?: 'primary' | 'secondary' | 'danger'
size?: 'sm' | 'md' | 'lg'
loading?: boolean
disabled?: boolean
}
const props = withDefaults(defineProps<Props>(), {
variant: 'primary',
size: 'md',
loading: false,
disabled: false,
})
const emit = defineEmits<{ click: [event: MouseEvent] }>()
const classes = computed(() => [
'btn',
`btn-${props.variant}`,
`btn-${props.size}`,
{ 'btn-loading': props.loading },
])
</script>
<template>
<button
:class="classes"
:disabled="disabled || loading"
@click="emit('click', $event)"
>
<span v-if="loading" class="spinner" />
<slot />
</button>
</template>
7. Production Checklist
| Category | Checklist |
|---|---|
| Security | CSP headers, CSRF, rate limiting, input validation |
| Performance | Lighthouse ≥ 90, bundle < 200KB, image optimization |
| Monitoring | Sentry, health checks, uptime monitoring |
| SEO | Meta tags, sitemap.xml, robots.txt, structured data |
| CI/CD | Automated tests, staging environment, rollback plan |
| Backup | Database backup, env secrets rotation, disaster recovery |
🎉 Complete the series Vue.js & Nuxt: From Basics to Advanced!