Skip to main content

Get Started in Minutes

This guide will walk you through setting up the portfolio website locally, running the development server, and making your first customizations.
Prerequisites: You’ll need Node.js 18+ and npm installed on your machine. Check your versions with node --version and npm --version.

Installation

1

Clone the Repository

First, clone the repository to your local machine:
git clone <repository-url>
cd kevin-portfolio
2

Install Dependencies

Install all required packages using npm:
npm install
This will install:
  • Astro (v5.7.10) - The web framework
  • Tailwind CSS (v3.4.17) - Styling framework
  • @astrojs/tailwind (v6.0.2) - Astro-Tailwind integration
  • Terser (v5.46.0) - JavaScript minifier for production builds
{
  "dependencies": {
    "@astrojs/tailwind": "^6.0.2",
    "astro": "^5.7.10",
    "tailwindcss": "^3.4.17"
  },
  "devDependencies": {
    "terser": "^5.46.0"
  }
}
3

Start Development Server

Launch the development server with hot module reloading:
npm run dev
The server will start at http://localhost:4321/ (Astro’s default port).
The development server includes:
  • Hot Module Replacement (HMR) - Instant updates without page refresh
  • TypeScript checking - Real-time type validation
  • Error overlay - Helpful error messages in the browser
4

Open in Browser

Navigate to http://localhost:4321/ in your browser.You’ll be automatically redirected to http://localhost:4321/es/ (Spanish homepage) since Spanish is the default language.To view the English version, go to http://localhost:4321/en/

Available Scripts

The portfolio includes four npm scripts for different workflows:
# Start development server with hot reload
npm run dev

Script Details

CommandDescriptionWhen to Use
npm run devStarts dev server at http://localhost:4321During development and content editing
npm run buildBuilds production-ready static files to dist/Before deployment or testing final output
npm run previewServes production build locallyTo test the built site before deploying
npm run astroAccess Astro CLI commandsFor advanced operations like astro add

Verify Installation

After starting the development server, you should see:
  • Hero Section: Profile image with animated gradient border
  • Language Selector: ES/EN toggle in the navigation
  • Theme Toggle: Moon/sun icon for dark mode
  • Smooth Animations: Sections fading in as you scroll
  • Responsive Design: Works on mobile, tablet, and desktop
  • CV Download Button: Language-aware resume download

Understanding the Route Structure

The portfolio uses Astro’s built-in i18n routing:
Routes:
├── /                    → Redirects to /es/ (default locale)
├── /es/                 → Spanish homepage
│   └── /es/index.astro
├── /en/                 → English homepage
│   └── /en/index.astro
└── /cv/
    ├── /es/            → Spanish CV (PDF)
    └── /en/            → English CV (PDF)

How Routing Works

The i18n configuration in astro.config.mjs:
i18n: {
  defaultLocale: 'es',
  locales: ['es', 'en'],
  routing: {
    prefixDefaultLocale: true,  // /es/ instead of /
  },
}
This ensures:
  • All routes are prefixed with the language code
  • Language can be extracted from the URL pathname
  • Translations are loaded based on the current route
  • CV downloads are language-aware

First Customizations

Now that you have the portfolio running, let’s make some quick customizations to understand the codebase.
1

Change the Hero Section Text

Open src/i18n/utils.ts and modify the hero translations:
src/i18n/utils.ts
export const translations = {
  es: {
    'hero.greeting': 'Hola, soy',
    'hero.name': 'Kevin Maximiliano Palma Romero',
    'hero.role': 'Azure Cloud Engineer',
    'hero.bio': 'Your custom bio in Spanish...',
    // ...
  },
  en: {
    'hero.greeting': "Hi, I'm",
    'hero.name': 'Kevin Maximiliano Palma Romero',
    'hero.role': 'Azure Cloud Engineer',
    'hero.bio': 'Your custom bio in English...',
    // ...
  }
}
Save the file and the page will automatically reload with your changes thanks to HMR.
2

Customize Theme Colors

Edit the primary color palette in tailwind.config.mjs:
tailwind.config.mjs
colors: {
  primary: {
    50: '#eff6ff',
    100: '#dbeafe',
    200: '#bfdbfe',
    300: '#93c5fd',
    400: '#60a5fa',
    500: '#3b82f6',  // Main primary color
    600: '#2563eb',
    700: '#1d4ed8',
    800: '#1e40af',
    900: '#1e3a8a',
    950: '#172554',
  },
  accent: {
    400: '#22d3ee',  // Cyan accent
    500: '#06b6d4',
    600: '#0891b2',
  },
}
These colors are used throughout:
  • Gradient borders and backgrounds
  • Button hover states
  • Badge colors
  • Link hover effects
3

Test Dark Mode

Click the theme toggle in the navigation bar (moon/sun icon):
  • Light Mode: Uses bg-slate-50 and text-slate-800
  • Dark Mode: Uses dark:bg-slate-950 and dark:text-slate-100
The theme preference is saved to localStorage and persists across page reloads:
src/components/ThemeToggle.astro
themeToggle?.addEventListener('click', () => {
  const isDark = document.documentElement.classList.toggle('dark');
  localStorage.setItem('theme', isDark ? 'dark' : 'light');
});
4

Switch Languages

Use the language selector in the navigation to toggle between Spanish and English:
  • Click ES → Navigates to /es/
  • Click EN → Navigates to /en/
All content updates automatically, including:
  • Navigation labels
  • Section headings
  • Case study descriptions
  • Button text
  • CV download links

Development Workflow

Here’s a recommended workflow for developing and customizing the portfolio:
1

Start Dev Server

Always keep the development server running:
npm run dev
2

Edit Component Files

Make changes to .astro files in src/components/:
src/components/
├── Hero.astro           # Landing section
├── About.astro          # Certifications & timelines
├── Projects.astro       # Case studies
├── Skills.astro         # Skills grid
├── Contact.astro        # Contact cards
├── CaseStudyCard.astro  # Reusable card component
├── Navbar.astro         # Navigation bar
├── Footer.astro         # Footer section
├── ThemeToggle.astro    # Dark mode toggle
└── LanguageSelector.astro # Language switcher
Changes are reflected immediately in the browser.
3

Update Translations

Modify content in src/i18n/utils.ts:
  • Add new translation keys
  • Update existing text
  • Maintain parity between es and en objects
Always update BOTH language objects to avoid fallback inconsistencies.
4

Test Across Languages

Switch between /es/ and /en/ to verify translations:
  • Check that new keys display correctly
  • Verify layout doesn’t break with longer text
  • Test RTL/LTR text rendering
5

Build for Production

Before deploying, create a production build:
npm run build
This generates optimized static files in the dist/ folder:
  • Minified HTML, CSS, and JavaScript
  • Optimized images (WebP format)
  • Console logs removed
  • Asset fingerprinting for cache busting
6

Preview Production Build

Test the production build locally:
npm run preview
This serves the dist/ folder exactly as it will appear in production.

Common Customizations

Replace the profile image in src/assets/imgProfile.png with your own photo.The Hero component uses Astro’s Image component for optimization:
src/components/Hero.astro
import { Image } from 'astro:assets';
import imgProfile from '../assets/imgProfile.png';

<Image
  src={imgProfile}
  alt="Your Name"
  width={256}
  height={256}
  format="webp"
  quality={80}
  loading="eager"
/>
Edit src/components/Projects.astro to modify case studies:
<CaseStudyCard
  title={t('case1.title')}
  challenge={t('case1.challenge')}
  solution={t('case1.solution')}
  tech={['PowerShell', 'Azure RBAC', 'Azure Policy']}
  icon="shield"
  challengeLabel={t('casestudies.challengeLabel')}
  solutionLabel={t('casestudies.solutionLabel')}
  stackLabel={t('casestudies.stackLabel')}
/>
Available icons: shield, search, migrate, cost, document
Modify the certifications section in src/components/About.astro:
<a
  href="https://learn.microsoft.com/..."
  target="_blank"
  rel="noopener noreferrer"
  class="certification-badge"
>
  AZ-104 — Azure Administrator
</a>
Add your own CV PDFs to:
  • public/cv/es/ - Spanish CV
  • public/cv/en/ - English CV
Update the filename in the Hero component if needed:
src/components/Hero.astro
<a
  href={`/cv/${lang}/CV Kevin Maximiliano Palma Romero - Azure Cloud Engineer 2026.pdf`}
  download
>
  {t('hero.cta')}
</a>

Troubleshooting

If port 4321 is occupied, Astro will automatically try the next available port (4322, 4323, etc.).Or specify a custom port:
npm run dev -- --port 3000
Check browser console for localStorage errors. The theme toggle requires:
localStorage.setItem('theme', 'dark');
localStorage.getItem('theme');
Ensure your browser allows localStorage access.
If translations don’t appear after editing utils.ts:
  1. Check for TypeScript errors in the console
  2. Verify both es and en objects have the same keys
  3. Restart the dev server: Ctrl+C then npm run dev
Common build issues:
# Clear Astro cache
rm -rf .astro node_modules/.astro

# Reinstall dependencies
rm -rf node_modules package-lock.json
npm install

# Try build again
npm run build

Next Steps

Now that you have the portfolio running locally, explore these guides:

Customization Guide

Learn how to customize components, colors, and animations

Internationalization

Manage translations and add new languages

Deployment

Deploy to Vercel, Netlify, or other hosting platforms

Components Reference

Detailed documentation for all Astro components

Need Help?

Live Demo

View the live portfolio at kevin-m-palma-r.vercel.app

Ready to make the portfolio your own? Continue to the Customization Guide to learn about advanced modifications.

Build docs developers (and LLMs) love