Skip to content

Astro Version

HaloLight Astro version is built on Astro 5, featuring Islands architecture with zero JS initial load and ultimate performance.

Live Preview: https://halolight-astro.h7ml.cn/

GitHub: https://github.com/halolight/halolight-astro

Tech Stack

TechnologyVersionDescription
Astro5.xIslands architecture framework
TypeScript5.xType safety
Tailwind CSS3.xAtomic CSS
ViteBuilt-inBuild tool
@astrojs/node9.xNode.js adapter
Vitest4.xUnit testing

Core Features

  • Islands Architecture: Zero JS by default, hydrate interactive components on demand
  • Multi-framework Support: Use React, Vue, Svelte components in the same project
  • Content-first: Static-first, ultimate initial load performance
  • SSR Support: Server-side rendering via @astrojs/node adapter
  • File-based Routing: Automatic routing based on file system
  • API Endpoints: Native support for REST API endpoints

Directory Structure

halolight-astro/
├── src/
│   ├── pages/                    # File-based routing
│   │   ├── index.astro          # Home
│   │   ├── privacy.astro        # Privacy Policy
│   │   ├── terms.astro          # Terms of Service
│   │   ├── auth/                # Auth pages
│   │   │   ├── login.astro
│   │   │   ├── register.astro
│   │   │   ├── forgot-password.astro
│   │   │   └── reset-password.astro
│   │   ├── dashboard/           # Dashboard pages
│   │   │   ├── index.astro      # Dashboard home
│   │   │   ├── analytics.astro  # Analytics
│   │   │   ├── users.astro      # User management
│   │   │   ├── accounts.astro   # Account management
│   │   │   ├── documents.astro  # Document management
│   │   │   ├── files.astro      # File management
│   │   │   ├── messages.astro   # Message center
│   │   │   ├── notifications.astro
│   │   │   ├── calendar.astro   # Calendar
│   │   │   ├── profile.astro    # Profile
│   │   │   └── settings/        # Settings
│   │   └── api/                 # API endpoints
│   │       └── auth/
│   │           ├── login.ts
│   │           ├── register.ts
│   │           ├── forgot-password.ts
│   │           └── reset-password.ts
│   ├── layouts/                 # Layout components
│   │   ├── Layout.astro         # Base layout
│   │   ├── AuthLayout.astro     # Auth layout
│   │   ├── DashboardLayout.astro # Dashboard layout
│   │   └── LegalLayout.astro    # Legal pages layout
│   ├── components/              # UI components
│   │   └── dashboard/
│   │       ├── Sidebar.astro    # Sidebar
│   │       └── Header.astro     # Top navigation
│   ├── styles/                  # Global styles
│   │   └── globals.css
│   └── assets/                  # Static assets
├── public/                      # Public assets
├── tests/                       # Test files
├── astro.config.mjs            # Astro config
├── tailwind.config.mjs         # Tailwind config
├── vitest.config.ts            # Test config
└── package.json

Quick Start

Installation

bash
git clone https://github.com/halolight/halolight-astro.git
cd halolight-astro
pnpm install

Environment Variables

bash
cp .env.example .env.local
env
# .env.local example
PUBLIC_API_URL=/api
PUBLIC_MOCK=true
PUBLIC_DEMO_EMAIL=admin@example.com
PUBLIC_DEMO_PASSWORD=123456
PUBLIC_SHOW_DEMO_HINT=true
PUBLIC_APP_TITLE=Admin Pro
PUBLIC_BRAND_NAME=Halolight

Start Development

bash
pnpm dev

Visit http://localhost:4321

Build for Production

bash
pnpm build
pnpm preview

Core Features

Islands Architecture

Astro's Islands architecture allows pages to be static HTML by default, with JavaScript only added to interactive components:

astro
---
// Static import, no JS
import StaticCard from '../components/StaticCard.astro';
// Interactive component (can be from React/Vue/Svelte)
import Counter from '../components/Counter.tsx';
---

<!-- Pure static, zero JS -->
<StaticCard title="Statistics" />

<!-- Hydrate on page load -->
<Counter client:load />

<!-- Hydrate when visible (lazy load) -->
<Counter client:visible />

<!-- Hydrate when browser is idle -->
<Counter client:idle />

Client Directives

DirectiveBehaviorUse Case
client:loadHydrate immediately on page loadCritical interactions
client:idleHydrate when browser is idleNon-critical interactions
client:visibleHydrate when element is visibleLazy-loaded components
client:onlyClient-side rendering onlyBrowser API dependent
client:mediaHydrate when media query matchesResponsive components

Layout System

astro
---
// layouts/DashboardLayout.astro
import Layout from './Layout.astro';
import Sidebar from '../components/dashboard/Sidebar.astro';
import Header from '../components/dashboard/Header.astro';

interface Props {
  title: string;
  description?: string;
}

const { title, description } = Astro.props;
const currentPath = Astro.url.pathname;
---

<Layout title={title} description={description}>
  <div class="min-h-screen bg-gray-50 dark:bg-gray-900">
    <Sidebar currentPath={currentPath} />
    <div class="lg:pl-64">
      <Header title={title} />
      <main class="p-4 lg:p-6">
        <slot />
      </main>
    </div>
  </div>
</Layout>

API Endpoints

Astro natively supports creating API endpoints:

typescript
// src/pages/api/auth/login.ts
import type { APIRoute } from 'astro';

export const POST: APIRoute = async ({ request }) => {
  const body = await request.json();
  const { email, password } = body;

  // Validation logic
  if (!email || !password) {
    return new Response(
      JSON.stringify({ success: false, message: 'Email and password are required' }),
      { status: 400, headers: { 'Content-Type': 'application/json' } }
    );
  }

  // Authentication logic...

  return new Response(
    JSON.stringify({
      success: true,
      message: 'Login successful',
      user: { id: 1, name: 'Admin', role: 'admin' },
      token: 'mock_token',
    }),
    { status: 200, headers: { 'Content-Type': 'application/json' } }
  );
};

File-based Routing

File PathURLDescription
src/pages/index.astro/Home
src/pages/auth/login.astro/auth/loginLogin
src/pages/dashboard/index.astro/dashboardDashboard
src/pages/dashboard/[id].astro/dashboard/:idDynamic route
src/pages/api/auth/login.ts/api/auth/loginAPI endpoint

Page Routes

PathPageDescription
/HomeLanding page
/auth/loginLoginUser login
/auth/registerRegisterUser registration
/auth/forgot-passwordForgot PasswordPassword recovery
/auth/reset-passwordReset PasswordSet new password
/dashboardDashboardData overview
/dashboard/analyticsAnalyticsChart statistics
/dashboard/usersUser ManagementUser list
/dashboard/accountsAccount ManagementAccount list
/dashboard/documentsDocument ManagementDocument list
/dashboard/filesFile ManagementFile list
/dashboard/messagesMessage CenterMessage list
/dashboard/notificationsNotificationsNotification list
/dashboard/calendarCalendarSchedule management
/dashboard/profileProfilePersonal information
/dashboard/settingsSettingsSystem settings
/privacyPrivacy PolicyLegal page
/termsTerms of ServiceLegal page

Configuration

Astro Configuration

javascript
// astro.config.mjs
import { defineConfig } from 'astro/config';
import tailwind from '@astrojs/tailwind';
import node from '@astrojs/node';

export default defineConfig({
  integrations: [tailwind()],
  output: 'server',  // SSR mode
  adapter: node({
    mode: 'standalone',
  }),
  server: {
    port: 4321,
    host: true,
  },
});

Output Modes

ModeDescriptionUse Case
staticStatic site generation (SSG)Blogs, documentation
serverServer-side rendering (SSR)Dynamic applications
hybridHybrid modePartially dynamic

Deployment

Node.js Server

bash
pnpm build
node ./dist/server/entry.mjs

Docker

dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN npm install -g pnpm && pnpm install --frozen-lockfile
COPY . .
RUN pnpm build
EXPOSE 4321
CMD ["node", "./dist/server/entry.mjs"]

Vercel

bash
# Install Vercel adapter
pnpm add @astrojs/vercel

# astro.config.mjs
import vercel from '@astrojs/vercel/serverless';

export default defineConfig({
  adapter: vercel(),
});

Cloudflare Pages

bash
# Install Cloudflare adapter
pnpm add @astrojs/cloudflare

# astro.config.mjs
import cloudflare from '@astrojs/cloudflare';

export default defineConfig({
  adapter: cloudflare(),
});

Testing

bash
# Run tests
pnpm test

# Generate coverage report
pnpm test --coverage

Comparison with Other Frameworks

FeatureAstroNext.jsNuxt
Default JS Size0 KB~80 KB~70 KB
Islands ArchitectureNative supportNot supportedNot supported
Multi-framework ComponentsSupportedNot supportedNot supported
SSG/SSRSupportedSupportedSupported
Learning CurveLowMediumMedium