Profiliuli is a modern, interactive portfolio website with a macOS-inspired interface, featuring dynamic video backgrounds and bilingual language support.
This project is based on macos-terminal-portfolio, built with Astro, React, and Tailwind CSS.
Name Origin: The name "Profiliuli" is derived from Profile + uli, following the naming convention of other projects in the portfolio (Pixuli, Stationuli). The "uli" suffix creates a consistent brand identity across projects.
Meaning:
- Profile represents a personal profile or professional portfolio, emphasizing the project's core purpose of showcasing personal competitiveness, skills, and achievements.
- The "uli" suffix maintains consistency with the existing project naming pattern, creating a cohesive brand identity.
Pronunciation: /ΛproΚfΙͺljuΛli/
- macOS-style Interface: Dock, toolbar, draggable windows, Notes app, GitHub project viewer
- Dynamic Video Backgrounds: Support for MP4 video wallpapers with automatic playback, loop, and mute
- Bilingual Support: Full English/Chinese language switching with i18n support
- Spotlight Search: Global search with fuzzy matching (Fuse.js), grouped results, and deep-linking
- AI Terminal: Chat endpoint powered by Groq
- Contact Form: In-app contact form modal that saves messages to Supabase Postgres
- Admin Dashboard: Dedicated
/adminroute with username/password login
Based on the original project, this version adds the following features:
1. Dynamic Video Background Support
- Support for MP4 video files as wallpapers
- Automatic playback, loop, and mute
- Smooth transitions between backgrounds
- Fallback to static images if video fails to load
- Video files should be placed in
public/background/video/
2. Complete Internationalization
- English/Chinese (Simplified) language switching (default: English)
- Language preference saved in localStorage
- All UI elements and content support both languages
- Configuration files organized by language:
src/config/en/andsrc/config/zh/ - Easy to extend to additional languages
3. Multi-language Configuration System
- Configuration files organized by language directory (
src/config/en/andsrc/config/zh/) - Supports localization of personal info, education, experience, skills, etc.
- Unified configuration loader and React hooks
4. Server-side Locale Inference (SEO follows language)
- Server infers locale via: query (
?lang=/?locale=) β cookie (locale=) βAccept-Language - SEO/OG meta tags are generated from
getUserConfig(locale)on the server
5. Localized Resume PDFs
- English:
/resume/resume-en.pdf - Chinese:
/resume/resume-zh.pdf
- Astro β Content-focused web framework
- React β UI interactivity
- Tailwind CSS β Utility-first styling
- TypeScript β Type safety
- Vercel β Hosting and analytics
- Supabase β Database and contact form storage
- Groq β AI terminal chat service
git clone https://github.com/your-username/portfolio
cd portfoliopnpm installCopy .env.example to .env and fill in (see .env.example for detailed comments):
# AI Terminal
GROQ_API_KEY=your_groq_api_key_here
# Site
PUBLIC_SITE_URL=https://your-domain.tld
# Supabase (server-only; do NOT expose in PUBLIC_ vars)
SUPABASE_URL=https://YOUR-PROJECT.supabase.co
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
# Admin dashboard credentials (server-only)
ADMIN_USERNAME=admin
ADMIN_PASSWORD=change_meRun this SQL in the Supabase SQL editor:
create table if not exists public.contact_messages (
id uuid primary key default gen_random_uuid(),
created_at timestamptz not null default now(),
name text not null,
email text not null,
message text not null,
time_on_page int,
ip text,
user_agent text
);
-- Enable RLS and do NOT add anon policies (server-only access via service_role)
alter table public.contact_messages enable row level security;Configuration files are located in src/config/ directory, organized by language:
English Configuration (src/config/en/):
personal.tsβ Personal information (name, role, location, website)education.tsβ Education backgroundexperience.tsβ Work experienceskills.tsβ Skills listsite.tsβ SEO and theme configurationsocial.tsβ Social media linkscontact.tsβ Contact informationprojects.tsβ Project configurationapps.tsβ Resume and Spotify configuration
Chinese Configuration (src/config/zh/):
- Same structure as English configuration, with Chinese translations
- Static Images: Place in
public/background/images/directory - Video Files: Place in
public/background/video/directory (MP4 format) - Background config: Manage available backgrounds in
src/config/background.ts(no hardcoding in pages)
pnpm run devThe development server will start at http://localhost:4321.
pnpm run buildpnpm run preview- Build the project
pnpm run build- Deploy to production
npx vercel deploy --prodOr deploy to preview first:
npx vercel deployThen select the deployment from the Vercel dashboard.
- Push code to GitHub
- Connect the repository in Vercel
- Configure environment variables (see below)
- Vercel will deploy automatically
Note: If GitHub auto-deployment has issues, use Method 1 (CLI deployment).
Configure in Vercel Project Settings β Environment Variables:
Required Variables:
PUBLIC_SITE_URLβ Production URL (e.g.,https://your-domain.tld)GROQ_API_KEYβ Groq API key (for AI Terminal)
Optional Variables (for contact form and admin dashboard):
SUPABASE_URLβ Supabase project URLSUPABASE_SERVICE_ROLE_KEYβ Supabase service role keyADMIN_USERNAMEβ Admin dashboard usernameADMIN_PASSWORDβ Admin dashboard password
- Ensure all environment variables are properly configured
- Check that
PUBLIC_SITE_URLis correct, as this affects SEO and Open Graph links - If using a custom domain, configure DNS records in Vercel
βββ src/
β βββ components/ # React components
β β βββ global/ # Global components (Dock, Toolbar, Spotlight, etc.)
β βββ layouts/ # Astro/React layouts
β βββ pages/ # Astro pages (includes API routes)
β βββ config/ # Configuration files
β β βββ en/ # English configuration
β β βββ zh/ # Chinese configuration
β β βββ loader.ts # Configuration loader
β β βββ hooks.tsx # React hooks
β βββ i18n/ # Internationalization
β β βββ locales/ # Language files (en.json, zh-CN.json)
β β βββ context.tsx # i18n Context
β βββ types/ # TypeScript type definitions
β βββ styles/ # Global styles
βββ public/ # Public assets
β βββ background/ # Background resources (images and videos)
βββ util/ # Utility scripts
βββ astro.config.mjs # Astro configuration
Cmd/Ctrl + Kβ Open Spotlight search?β Show shortcuts overlayCtrl/Cmd + βorF3β Open Mission ControlCmd/Ctrl + Cβ Open Contact form
Configuration files are organized by language in src/config/en/ and src/config/zh/:
- Localized Content:
personal.ts,education.ts,experience.ts,skills.ts,site.ts,apps.ts(resume) - Non-localized Content:
social.ts,contact.ts,projects.ts,spotify(loaded fromsrc/config/en/only)
In React Components:
import { useUserConfig } from '../../config/hooks';
function MyComponent() {
const userConfig = useUserConfig(); // Automatically loads config based on current language
// ...
}In Astro Pages (server-side, locale-aware):
import { getUserConfig } from '../config/loader';
import { inferServerLocale } from '../i18n/server';
const url = new URL(Astro.request.url);
const locale = inferServerLocale({ request: Astro.request, url });
const config = getUserConfig(locale); // 'en' | 'zh-CN'- β macOS-style interface (Dock, toolbar, draggable windows)
- β Dynamic video background support
- β English/Chinese bilingual switching
- β Spotlight global search
- β Mission Control window management
- β AI Terminal chat
- β Contact form (Supabase storage)
- β Admin dashboard
- β Responsive design
- β SEO optimization
- β Accessibility support
- Original Project: macos-terminal-portfolio
- Original Author: Johnny Culbreth (Austin, TX)
- Modified by: aabdoo23 (Giza, Egypt)
- Enhanced by: trueLoving - Added dynamic video backgrounds and bilingual language support
This project is licensed under the MIT License - see the LICENSE file for details.