Files
aranroig.com/AGENTS.md
BinarySandia04 bbc34c1b12
All checks were successful
Build and Deploy Nuxt / build (push) Successful in 35s
A lot of AI slop
2026-06-08 19:36:45 +02:00

5.2 KiB

aranroig.com

Monorepo for aranroig.com — a personal portfolio website with blog, art gallery, and project showcase.

Stack

  • Frontend: Nuxt 4 + Vue 3 + TypeScript + SCSS
  • Backend: Express 5 + Mongoose (MongoDB)
  • i18n: @nuxtjs/i18n (English, Spanish, Catalan)
  • Content: Nuxt Content v3 with Zod-sourced Markdown collections
  • Image optimization: @nuxt/image
  • Build: Vite
  • Deployment: Docker Compose + Nginx reverse proxy + Gitea Actions CI/CD
  • Process management: PM2 (production)

Project Structure

├── backend/              # Express API server (port 5000)
│   └── src/
│       ├── index.js      # Entry point, single /api/test endpoint
│       └── db.js         # MongoDB connection via Mongoose
├── frontend/             # Nuxt application
│   ├── app/
│   │   ├── assets/css/   # Global SCSS: colors.scss (themes), fonts.scss, main.scss
│   │   ├── components/   # Vue components (TUI-styled)
│   │   │   ├── layouts/  # Page layout wrappers
│   │   │   ├── parts/    # Header, footer, navigation pieces
│   │   │   └── content/  # Blog, art content components
│   │   ├── composables/  # useApi(), theme.ts (light/dark + accent colors)
│   │   ├── i18n.config.ts# VueI18n fallback locale setup
│   │   └── pages/        # File-based routing (index, blog, art, contact)
│   ├── content/          # Markdown collections organized by locale
│   │   ├── fixed/        # Static pages per locale
│   │   ├── blog/         # Blog posts
│   │   ├── art/          # Art pieces
│   │   └── projects/     # Project cards
│   ├── i18n/locales/     # en.json, es.json, ca.json translation files
│   ├── content.config.ts # Content collection schemas (Zod)
│   └── nuxt.config.ts    # Nuxt config: modules, i18n, runtime config
├── docker-compose.yml    # Services: nginx, frontend, backend
├── nginx.conf            # Reverse proxy routing /api/ → backend:5000
├── ecosystem.config.js   # PM2 production deployment config
└── .gitea/workflows/     # Gitea Actions CI/CD (deploy on master push)

Commands

From repo root:

Command Description
npm run dev Run frontend + backend concurrently with logging prefixes [BACKEND] and [FRONTEND]
npm install Install monorepo dependencies (triggers frontend/postinstall)

In frontend/:

Command Description
npm run dev Nuxt dev server with live reload
npm run build Production build with .env.production
npm run generate Static site generation
npm run preview Preview built production output

In backend/:

Command Description
npm run dev Nodemon on src/index.js (auto-restart, port 5000)

Development

  • Use the monorepo root script: npm run dev — runs both frontend and backend in parallel.
  • Frontend uses the ~/ alias mapping to frontend/app/. Auto-imported composables include useAsyncData, useI18n, useRoute, useLocalePath, etc.
  • Backend reads .env.development or .env.production based on NODE_ENV. Requires DB_URI for MongoDB.
  • Frontend runtime config key public.apiBaseUrl sets the backend API URL used by useApi().
  • Content lives in frontend/content/ under collection folders (blog, fixed, art, projects), each with locale subdirectories (en, es, ca).

Code Style

  • Vue SFCs use <script setup> (TypeScript via lang="ts" where needed, plain JS otherwise).
  • All styling is SCSS with scoped styles per component. Page-level blog/art pages use global styles.
  • Mobile-first breakpoints: 600px, 900px, 1200px (max-width queries).
  • File names: kebab-case for components and pages.
  • CSS variables driven by SCSS maps define themes (light/dark) and accent colors.
  • TUI aesthetic: box-drawing characters, monospace font (Hermit / "Hurmit" via Nerd Fonts), steps() easing transitions, pixel-art SVG elements.

Content Collections

Content frontmatter is validated with Zod schemas defined in frontend/content.config.ts:

Collection Fields
blog title, slug, date, description
art title, slug, thumb, date
projects title, slug, description, link, tech (array)
fixed title, slug, description

Write Markdown files under the corresponding collection folder with locale subdirectories. Frontmatter must conform to the Zod schema.

Theming

  • Theme selector switches between light/dark modes and accent color palettes (dragon-themed names: katlum, solus, silang, nozt, albor).
  • Preferences persist in localStorage. Respects prefers-color-scheme on first visit.
  • Theme setup runs via setupTheme() composable called on app mount (app.vue).

Deployment

  1. Gitea Actions CI/CD triggers on push to master, builds Docker images, pushes to Gitea registry.
  2. SSHs into deploy host and runs docker-compose pull && docker-compose up -d.
  3. For manual deployment, docker-compose.yml orchestrates nginx + frontend + backend services.
  4. Production process management uses PM2 via ecosystem.config.js.