A high-performance, SEO-optimized, multi-language single-page site featuring a real Live2D Cubism model that follows your cursor, blinks, breathes, and changes expression β built with Astro, in 7 languages, shipping only ~8 kB gzipped on first load. π
β If this project makes you smile, please give it a star β it genuinely helps!
Meet Haru (γγ«) β a genuine Live2D Cubism 4 model rendered with pixi-live2d-display and PixiJS. She's not a static image or a CSS trick: she's a real rigged VTuber-style model that reacts to you in real time.
The engineering challenge β and what makes this repo worth studying β is that Live2D is heavy (a WebGL runtime plus a ~2 MB model). This project proves you can wrap that in a page that is still fast and ranks well, by prerendering everything to static HTML and lazy-loading the runtime completely off the critical path.
π topshopifydev.github.io/wife-2d-anime
π‘ Tip: after you push, add a screenshot or GIF here (e.g.
docs/preview.gif) β repos with a visual get far more stars.
| π Real Live2D model | Genuine Cubism 4 rig β cursor tracking, auto-blink, breathing, hair physics, 8 expressions, tap/idle motions |
| β‘ Blazing fast | Static prerender + lazy WebGL runtime β ~4 kB JS + inlined CSS on first paint |
| π SEO-first | Full metadata, Open Graph, Twitter cards, JSON-LD, sitemap, robots, canonical URLs |
| π 7 languages | Separate prerendered page per language with hreflang β the search-engine-correct way |
| π Light / dark theme | "Sakura" & "Night", persisted to localStorage |
| π Delightful details | Falling sakura petals, typewriter intro, speech bubbles, and a hidden Konami-code surprise |
| π± Responsive & a11y | Phone β ultrawide, semantic HTML, prefers-reduced-motion respected |
| π§© Zero-dependency runtime | Cubism Core, PixiJS & the model are vendored β works offline, no CDN calls |
| Layer | Choice | Why |
|---|---|---|
| Framework | Astro 5 | Ships zero JS by default; prerenders static HTML β ideal for SEO + performance |
| Character | Live2D Cubism 4 + pixi-live2d-display + PixiJS 6 |
A real, animated 2D model β not an image |
| i18n | Astro i18n routing + a single translations table | One crawlable URL per language, auto hreflang |
| Styling | Hand-written CSS (system fonts, CSS variables) | No webfont cost, no CLS, tiny |
| Images | sharp build script |
Generates the OG image + PWA icons from SVG |
- Prerendered static HTML with real, crawlable content (
<h1>, profile, features, FAQ) β not an empty canvas <title>, meta description, canonical, robots, Open Graph + Twitter Card (with a generated 1200Γ630og.png)- JSON-LD structured data (
WebSite,Person,FAQPageβ rich-result eligible) β localized per language - Sitemap (
@astrojs/sitemap),robots.txt, PWAmanifest.webmanifest+ maskable icons - Multi-language SEO: one URL per language, reciprocal
hreflang+x-default, per-localelang/og:locale/inLanguage - Critical JS ~4.4 kB; the heavy Live2D runtime is lazy-loaded via
IntersectionObserver+requestIdleCallback - CSS inlined (no render-blocking stylesheet) Β· system fonts (no download, no layout shift)
Seven languages, each a separate static page with reciprocal hreflang alternates:
π―π΅ ζ₯ζ¬θͺ β / (default) |
π¬π§ English β /en/ |
πͺπΈ EspaΓ±ol β /es/ |
π©πͺ Deutsch β /de/ |
πΉπ· TΓΌrkΓ§e β /tr/ |
π΅πΉ PortuguΓͺs β /pt/ |
π¨π³ δΈζ β /zh/ |
A globe menu switches languages with plain links (works without JS). All strings live in one file β src/i18n/translations.js.
Add a language: add its code to src/i18n/config.js and a matching entry in translations.js. The route, sitemap, and hreflang alternates generate automatically.
git clone https://github.com/topshopifydev/wife-2d-anime.git
cd wife-2d-anime
npm install
npm run dev # dev server β http://localhost:4321
npm run build # static build β dist/
npm run preview # preview the production build
β οΈ Before deploying, setsiteinastro.config.mjsand the URL inpublic/robots.txtto your final domain β they feed canonical URLs, the sitemap, and Open Graph tags.
Regenerate the OG image / icons after editing scripts/og.svg:
node scripts/gen-assets.mjswife-2d-anime/
βββ astro.config.mjs # site URL, i18n, sitemap, CSS inlining
βββ src/
β βββ layouts/Base.astro # SEO <head>: meta, OG, hreflang, JSON-LD, theme
β βββ components/Page.astro # the whole localized page + lazy Live2D loader
β βββ pages/
β β βββ index.astro # default locale (ja) at /
β β βββ [locale]/index.astro # /en/, /es/, /de/, /tr/, /pt/, /zh/
β βββ i18n/
β β βββ config.js # locale list, hreflang / og:locale maps
β β βββ translations.js # all UI strings for every language
β βββ styles/global.css # theme, layout, petals, language menu
βββ public/
β βββ vendor/ # Cubism Core, PixiJS, pixi-live2d-display (bundled)
β βββ assets/live2d/haru/ # the Haru Cubism model (moc3, textures, motionsβ¦)
β βββ og.png Β· icon-*.png Β· favicon.svg Β· manifest.webmanifest Β· robots.txt
βββ scripts/ # og.svg + gen-assets.mjs (raster OG/icons via sharp)
| Change⦠| Where |
|---|---|
| Use a different Live2D model | drop it in public/assets/live2d/β¦, set MODEL_URL in src/components/Page.astro |
| Any text, in any language | src/i18n/translations.js (name, tagline, dialogue, profile, features, FAQ) |
| Add / remove a language | src/i18n/config.js + translations.js (see Languages above) |
| Which expression each mood plays | moods array in translations.js (exp / motion per entry) |
| Colors & theme | CSS variables in src/styles/global.css |
GitHub Pages (great for a portfolio piece):
npm run build, then publishdist/withactions/deploy-pages.- For a project page at
topshopifydev.github.io/wife-2d-anime/, setbase: '/wife-2d-anime/'inastro.config.mjsor deploy from a repo namedtopshopifydev.github.ioto serve it at the root (simplest β the absolute asset paths just work).
Vercel / Netlify / Cloudflare Pages β zero config: build npm run build, output dist. (Astro is auto-detected.)
- Code (this repo): MIT β free to use, remix, and share.
- Live2D Cubism Core β Β© Live2D Inc., under the Live2D Cubism Core License.
- Haru model (
public/assets/live2d/haru/) β a Live2D sample model, Β© Live2D Inc., under the Live2D Free Material License. Review Live2D's terms before commercial use and keep the copyright notice. - PixiJS β MIT Β· pixi-live2d-display by guansss β MIT.
Not affiliated with or endorsed by Live2D Inc.
Sid Lukkassen
If you build something with this, I'd love to see it β open an issue or mention me. πΈ
Enjoyed it? Drop a β β it means a lot and helps others discover the project.
Made with π & Astro by Sid Lukkassen Β· γγγγγͺγγγ πΈ