feat: migrate landing page from Next.js to Astro

Replaces the heavy Next.js SSR app with Astro static site:
- Zero JS shipped for static pages (hero, community, CTA, footer)
- Server-side data fetching in Astro frontmatter (events, hackathon, testimonials)
- Only 4 React islands for interactive parts (mobile menu, roadmap voting, testimonials home, feature request)
- Google Fonts via <link> instead of next/font
- Nix build changed from Node.js systemd service to static nginx (mkStaticAppModule)
- npmDepsHash needs update (set to fake hash, CI will provide correct one)

Performance gains:
- No Node.js server process needed (was using ~10MB RAM)
- No Next.js runtime JS (~200KB+ saved)
- No framer-motion bundle (~130KB saved)
- Static HTML served directly by nginx

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
maulanasdqn
2026-04-10 22:10:52 +07:00
co-authored by Claude Opus 4.6
parent 0ade3c3e50
commit 95bf09c2fa
61 changed files with 4141 additions and 2259 deletions
+51
View File
@@ -0,0 +1,51 @@
---
import '../styles/globals.css';
interface Props {
title?: string;
description?: string;
}
const {
title = 'IMPHNEN - Ingin Menjadi Programmer Handal Namun Enggan Ngoding',
description = 'Komunitas belajar programming untuk semua level',
} = Astro.props;
---
<!doctype html>
<html lang="id">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{title}</title>
<meta name="description" content={description} />
<!-- Open Graph -->
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:url" content="https://imphnen.dev" />
<meta property="og:image" content="https://imphnen.dev/imphnen-group-cover.webp" />
<meta property="og:image:alt" content="IMPHNEN - Ingin Menjadi Programmer Handal Namun Enggan Ngoding" />
<meta property="og:image:width" content="2550" />
<meta property="og:image:height" content="945" />
<!-- Twitter -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content={title} />
<meta name="twitter:description" content={description} />
<meta name="twitter:image" content="https://imphnen.dev/imphnen-group-cover.webp" />
<!-- Google Fonts: Poppins -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700;800&display=swap"
rel="stylesheet"
/>
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
</head>
<body class="font-[Poppins,sans-serif] antialiased">
<slot />
</body>
</html>
+22
View File
@@ -0,0 +1,22 @@
---
import Base from './Base.astro';
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';
interface Props {
title?: string;
description?: string;
}
const { title, description } = Astro.props;
---
<Base title={title} description={description}>
<div class="flex min-h-screen flex-col">
<Header />
<main class="flex-1">
<slot />
</main>
<Footer />
</div>
</Base>