YoSpace
A personal homepage project built with Next.js App Router. It includes a profile page, blog, links page, and a site-wide music player. The codebase is organized in a modular, component-driven way to keep the UI responsive and maintainable.
The original inspiration and UI/UX direction come from KumaKorin/react-homepage. Author’s homepage: KumaKorin
Feature Overview
- Home: profile and social links
- Blog: post list and post detail, with Markdown support
- Links: link cards
- Music Player: global floating player with playlist, drag-and-drop reorder, progress/volume dragging, and play mode switching
- Theme: light/dark mode
- i18n: Chinese/English switch (controlled by env var)
Tech Stack
- Framework: Next.js (App Router)
- Language: TypeScript
- UI: React + CSS Modules
- Animation: framer-motion
- Markdown: gray-matter + react-markdown + remark-gfm + rehype-raw
- Syntax highlighting: react-syntax-highlighter (with one-click copy)
- Drag & drop: @hello-pangea/dnd (reference: A very detailed guide to React drag-and-drop components)
- Linting: ESLint
Quick Start
Local development
pnpm is recommended (this repo includes pnpm-lock.yaml).
- Install dependencies
bash1pnpm install
- Configure environment variables
Copy .env.example to .env or .env.local, then adjust values as needed.
- Start development server
bash1pnpm dev
Open: http://localhost:3000
Deploy on Vercel
One-click repo creation
Click the button to create a repo in your GitHub automatically. Vercel will handle the deployment end-to-end without local setup:
Common Scripts
bash1# Local development 2pnpm dev 3 4# Build 5pnpm build 6 7# Start locally (run build first) 8pnpm start 9 10# Lint 11pnpm lint
Environment Variables
This project uses NEXT_PUBLIC_* variables (exposed to the browser). Do not put secrets in these variables.
See .env.example for a full list. Key options:
Server Actions (Proxy / CDN)
SERVER_ACTIONS_ALLOWED_ORIGINS: Comma-separated allowlist of origin domains that can trigger Server Actions.- When to use: If you put the site behind a CDN/reverse proxy and see errors like
Invalid Server Actions requestcaused byx-forwarded-hostnot matchingorigin. - Format: Domains only (may include port). Do not include protocol (
https://) or paths. - Example:
yospace.waveyo.cn,yospace-vercel.waveyo.cn
Contentful (optional)
The repo keeps Contentful-related variables, but the current blog implementation uses local Markdown files by default.
NEXT_PUBLIC_CONTENTFUL_SPACE_IDNEXT_PUBLIC_CONTENTFUL_DELIVERY_TOKENNEXT_PUBLIC_CONTENTFUL_BLOG_MODELNEXT_PUBLIC_CONTENTFUL_BLOG_ORDER_TYPE
Blog
NEXT_PUBLIC_BLOG_ITEMS_PER_PAGE: items per pageNEXT_PUBLIC_BLOG_MODE:internal(in-app route) orexternal(redirect to an external blog)NEXT_PUBLIC_BLOG_URL: external blog URL (only used when mode isexternal)
i18n
NEXT_PUBLIC_I18N: enable language switch (true/false)
Site Info
NEXT_PUBLIC_SITE_TITLE/NEXT_PUBLIC_SITE_TITLE_ENNEXT_PUBLIC_NAV_TITLE/NEXT_PUBLIC_NAV_TITLE_ENNEXT_PUBLIC_SITE_DESCRIPTION/NEXT_PUBLIC_SITE_DESCRIPTION_ENNEXT_PUBLIC_PROFILE_NAMES/NEXT_PUBLIC_PROFILE_NAMES_EN: multiple names separated by commasNEXT_PUBLIC_PROFILE_IMAGENEXT_PUBLIC_FAVICON_URL
ICP/Regulatory Info (optional)
NEXT_PUBLIC_ICP_CODENEXT_PUBLIC_POLICE_LICENSE
Music Player
NEXT_PUBLIC_MUSIC_API_BASE: music API base URLNEXT_PUBLIC_MUSIC_PLAYLIST_ID: playlist ID
By default, next.config.ts contains a rewrite proxy for the music API:
- Local path:
/api/music-proxy/* - Proxied to:
https://netmusic.waveyo.cn/*
If NEXT_PUBLIC_MUSIC_API_BASE is set to https://netmusic.waveyo.cn/, the player will prefer the in-app proxy path to reduce CORS issues.
The API provided by
netmusic.waveyo.cnis free to use, but it costs resources to operate and maintain. If you use this API, consider supporting it at dq.waveyo.cn and note that the donation is for the Music API.
Friend Links
Edit src\data\friendLinks.json to manage your friend links.
JSON format example (subtitle is optional):
json1[ 2 { 3 "title": "WaveYo", 4 "subtitle": "WaveYo HomePage", 5 "link": "https://home.waveyo.cn", 6 "avatar": "https://cloud.waveyo.cn//Services/websites/home/images/icon/favicon.ico" 7 }, 8 { 9 "title": "KumaKorin", 10 "link": "https://korin.im", 11 "avatar": "https://m1.miaomc.cn/uploads/20210623_b735dde7c665d.jpeg" 12 }, 13]
Social Links
Edit src\data\socialLinks.json to manage your social links.
JSON format example:
json1[ 2 { 3 "name": "bilibili", 4 "url": "https://space.bilibili.com/204818057", 5 "iconPackage": "fa6", 6 "iconName": "FaBilibili" 7 }, 8 { 9 "name": "email", 10 "url": "mailto:support@email.example", 11 "iconPackage": "md", 12 "iconName": "MdEmail" 13 }, 14 { 15 "name": "github", 16 "url": "https://github.com", 17 "iconPackage": "fa6", 18 "iconName": "FaGithub" 19 } 20]
For iconName and iconPackage, see React Icons (GitHub) and the React Icons docs.
Content Management (Local Markdown)
Local posts live in: src/content/posts/
- English:
slug.md - Chinese:
slug.zh-CN.md
Posts use Front Matter for metadata. Example:
md1--- 2title: "Welcome to My Blog" 3description: "This is a sample post using a local Markdown file." 4date: "2026-01-20T10:00:00Z" 5tags: ["Next.js", "Markdown"] 6--- 7 8Post content...
Directory Structure
text1src/ 2 app/ Next.js routes and layout (App Router) 3 actions/ Server Actions (e.g. blog content reading) 4 components/ Feature components 5 Blog/ Blog components 6 Links/ Links components 7 MusicPlayer/ Music player (Hooks + sub-components) 8 Common/ Shared UI (Header/Footer/ProgressBar, etc.) 9 content/posts/ Local Markdown posts 10 context/ Global context (i18n) 11 data/ Static data (social links, friend links) 12 locales/ Translation dictionaries 13 utils/ Utilities and content loading logic 14public/ Static assets
Deployment Notes
- Suitable for Vercel, Netlify, or a self-hosted Node service.
- Configure environment variables before deploying (especially site config and music API).
- Build with
pnpm build, start withpnpm start.
Deploy your own Music API?
This project’s music API is based on API Enhanced. You can deploy your own instance by following that repository’s documentation.
FAQ
Music won't play / playlist failed to load
- Check whether
NEXT_PUBLIC_MUSIC_API_BASEandNEXT_PUBLIC_MUSIC_PLAYLIST_IDare correct. - The API provided by
netmusic.waveyo.cnis free to use but requires ongoing maintenance. If you rely on it, consider supporting it at dq.waveyo.cn and note that the donation is for the Music API.
Post list is empty
- Make sure there are post files under
src/content/posts/for your language. - Chinese posts should be named
*.zh-CN.md, and English posts should be*.md.