Modern, multilingual portfolio built with React + Vite, featuring smooth animations and production-ready SEO optimization.
- π Multilingual - English (default), Portuguese, Japanese with automatic detection
- π± Fully Responsive - Mobile-first design with fluid animations
- π Rich Animations - GSAP and Framer Motion integrations
- π SEO Optimized - Hybrid system: static HTML for crawlers + dynamic meta tags
- π± Social Media Ready - Open Graph, Twitter Cards with multilingual support
- β‘ Performance Focused - Code splitting, lazy loading (~300KB gzipped)
- βΏ Accessible - WCAG 2.1 AA compliant with keyboard navigation
- π¨ Modern Stack - React 18, Vite 5, SCSS, React Router v7
# Install dependencies
npm install
# Start development server
npm run dev
# Build for production
npm run build
# Preview production build
npm run preview| Language | Home | About | Portfolio | Contact |
|---|---|---|---|---|
| English | / |
/about |
/portfolio |
/contact |
| Portuguese | /pt/ |
/pt/about |
/pt/portfolio |
/pt/contact |
| Japanese | /ja/ |
/ja/about |
/ja/portfolio |
/ja/contact |
- React 18 - UI library
- Vite 5 - Build tool & dev server
- React Router DOM v7 - Client-side routing
- SCSS - Styling with responsive mixins
- Framer Motion - React animation library
- GSAP - Advanced scroll animations
- react-i18next - Translation management
- i18next-browser-languagedetector - Automatic language detection
- React Helmet Async - Dynamic meta tags
- Custom static HTML generator - Pre-rendered pages for crawlers
- nginx - Crawler detection & routing
- Formspree - Contact form backend
src/
βββ components/ # Reusable components
β βββ SEO.jsx # Dynamic meta tags
β βββ Router.jsx # Client-side routing
β βββ Navbar/ # Navigation component
β βββ Social/ # Social media links
β βββ ...
βββ pages/ # Page components
β βββ Home/
β βββ About/
β βββ Portfolio/
β βββ Contact/
βββ config/ # Configuration files
β βββ constants.js # Shared constants
β βββ internationalization/
βββ data/ # Static data
β βββ projects.js # Portfolio projects
βββ utils/ # Utility functions
β βββ languageUtils.js
β βββ mixins.scss
β βββ variables.scss
βββ assets/ # Images, icons, fonts
scripts/
βββ generate-static-seo.mjs # Static HTML generation
βββ generate-sitemap.mjs # XML sitemap generation
public/
βββ og-image.png # Social sharing (EN)
βββ og-image-pt.png # Social sharing (PT)
βββ og-image-ja.png # Social sharing (JA)
βββ resume.pdf # Resume file
βββ robots.txt # Crawler directives
βββ site.webmanifest # PWA manifest
The portfolio uses a hybrid SEO system:
- For crawlers (Facebook, WhatsApp, Google): Pre-rendered static HTML pages with correct localized meta tags
- For users: Full React SPA with dynamic meta tags via React Helmet
Why? Social media crawlers don't execute JavaScript, so dynamic meta tags don't work. The solution: nginx detects crawlers and serves them static pages.
Request to /pt/contact
β
nginx.conf (crawler detection)
β
Is crawler? ββYesβ Serve /pt/contact/index.html (static)
β
No
β
Serve SPA β React Router β SEO.jsx (dynamic)
Production Build (gzipped):
βββ vendor.js 141KB (React + ReactDOM)
βββ animations.js 179KB (Framer Motion + GSAP)
βββ i18n.js 81KB (Internationalization)
βββ main.js 121KB (App core)
βββ components.js 40KB (Components)
βββ utils.js 31KB (Utilities)
ββββββββββββββββββββββββββββββββββββββββ
Total: ~300KB
- β Route-based code splitting with React.lazy()
- β Vendor chunk separation
- β Native image lazy loading
- β Optimized Vite build configuration
# Development
npm run dev # Start dev server (http://localhost:5173)
# Building
npm run build # Build + generate sitemap + static SEO pages
npm run build:simple # Build only (without post-build scripts)
npm run generate:sitemap # Generate sitemap.xml only
npm run preview # Preview production build (http://localhost:4173)Current Setup: CapRover with nginx
Also compatible with:
- Netlify
- Vercel
- Any static host with nginx/Apache configuration
Required Files:
nginx.conf- Production nginx configurationDockerfile- Container setup (CapRover)dist/- Build output
None required! The app is fully static after build.
# Test production build locally
npm run build && npm run preview
# Test different languages
open http://localhost:4173/pt/contact
open http://localhost:4173/ja/about
# Test social media sharing
# Facebook: https://developers.facebook.com/tools/debug/
# Twitter: https://cards-dev.twitter.com/validator- Add project images to
src/assets/portfolio/ - Update
src/data/projects.js:'new-project-id': { images: [newProjectImg], imagePositions: ['center top'], techs: ['React', 'Node.js'], link: 'https://...', repository: 'https://github.com/...' }
- Add translations in all language files:
{ "projects": [ { "id": "new-project-id", "title": "...", "description": "..." } ] }
Edit seo section in translation files:
{
"seo": {
"home": {
"title": "...",
"description": "...",
"keywords": "..."
}
}
}Run npm run build to regenerate static SEO pages.
Edit src/utils/variables.scss:
$dark: #242424;
$blue: #2bcab6;
$white: #ffffff;Currently using Google Fonts (Space Grotesk). To self-host:
npm install @fontsource/space-groteskUpdate src/main.jsx:
import '@fontsource/space-grotesk/400.css'
import '@fontsource/space-grotesk/700.css'Defined in src/utils/mixins.scss:
$breakpoints: (
'mobile': 480px,
'tablet': 768px,
'tablet-landscape': 1024px,
'desktop': 1024px,
'large': 1400px
);This is a personal portfolio, but you're welcome to:
- Report bugs via GitHub Issues
- Suggest improvements
- Use as inspiration for your own portfolio
MIT License - feel free to use this project as inspiration for your own portfolio.
- Framer Motion - Beautiful animations
- GSAP - Advanced scroll effects
- React Helmet Async - SEO meta tag management
- Formspree - Simple form backend
Built with β€οΈ by Vitor Rita