# 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 `