Arquitecto de Soluciones Principal y Consultor Tecnológico de Andru.ia. Diagnostica y traza la hoja de ruta óptima para proyectos de IA en español.
日本語の概要は準備中です。原文の説明を表示しています。
Build content-focused websites with Astro — zero JS by default, islands architecture, multi-framework components, and Markdown/MDX support.
インストール方法を見るインストールする前に、エージェントに与えられる指示の中身を確認できます。
Astro is a web framework designed for content-rich websites — blogs, docs, portfolios, marketing sites, and e-commerce. Its core innovation is the Islands Architecture: by default, Astro ships zero JavaScript to the browser. Interactive components are selectively hydrated as isolated "islands." Astro supports React, Vue, Svelte, Solid, and other UI frameworks simultaneously in the same project, letting you pick the right tool per component.
.astro files, Astro.props, content collections, or client: directivesnpm create astro@latest my-site
cd my-site
npm install
npm run dev
Add integrations as needed:
npx astro add tailwind # Tailwind CSS
npx astro add react # React component support
npx astro add mdx # MDX support
npx astro add sitemap # Auto sitemap.xml
npx astro add vercel # Vercel SSR adapter
Project structure:
src/
pages/ ← File-based routing (.astro, .md, .mdx)
layouts/ ← Reusable page shells
components/ ← UI components (.astro, .tsx, .vue, etc.)
content/ ← Type-safe content collections (Markdown/MDX)
styles/ ← Global CSS
public/ ← Static assets (copied as-is)
astro.config.mjs ← Framework config
.astro files have a code fence at the top (server-only) and a template below:
---
// src/components/Card.astro
// This block runs on the server ONLY — never in the browser
interface Props {
title: string;
href: string;
description: string;
}
const { title, href, description } = Astro.props;
---
<article class="card">
<h2><a href={href}>{title}</a></h2>
<p>{description}</p>
</article>
<style>
/* Scoped to this component automatically */
.card { border: 1px solid #eee; padding: 1rem; }
</style>
src/pages/index.astro → /
src/pages/about.astro → /about
src/pages/blog/[slug].astro → /blog/:slug (dynamic)
src/pages/blog/[...path].astro → /blog/* (catch-all)
Dynamic route with getStaticPaths:
---
// src/pages/blog/[slug].astro
export async function getStaticPaths() {
const posts = await getCollection('blog');
return posts.map(post => ({
params: { slug: post.slug },
props: { post },
}));
}
const { post } = Astro.props;
const { Content } = await post.render();
---
<h1>{post.data.title}</h1>
<Content />
Content collections give you type-safe access to Markdown and MDX files:
// src/content/config.ts
import { z, defineCollection } from 'astro:content';
const blog = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
date: z.coerce.date(),
tags: z.array(z.string()).default([]),
draft: z.boolean().default(false),
}),
});
export const collections = { blog };
---
// src/pages/blog/index.astro
import { getCollection } from 'astro:content';
const posts = (await getCollection('blog'))
.filter(p => !p.data.draft)
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf());
---
<ul>
{posts.map(post => (
<li>
<a href={`/blog/${post.slug}`}>{post.data.title}</a>
<time>{post.data.date.toLocaleDateString()}</time>
</li>
))}
</ul>
By default, UI framework components render to static HTML with no JS. Use client: directives to hydrate:
---
import Counter from '../components/Counter.tsx'; // React component
import VideoPlayer from '../components/VideoPlayer.svelte';
---
<!-- Static HTML — no JavaScript sent to browser -->
<Counter initialCount={0} />
<!-- Hydrate immediately on page load -->
<Counter initialCount={0} client:load />
<!-- Hydrate when the component scrolls into view -->
<VideoPlayer src="/demo.mp4" client:visible />
<!-- Hydrate only when browser is idle -->
<Analytics client:idle />
<!-- Hydrate only on a specific media query -->
<MobileMenu client:media="(max-width: 768px)" />
---
// src/layouts/BaseLayout.astro
interface Props {
title: string;
description?: string;
}
const { title, description = 'My Astro Site' } = Astro.props;
---
<html lang="en">
<head>
<meta charset="utf-8" />
<title>{title}</title>
<meta name="description" content={description} />
</head>
<body>
<nav>...</nav>
<main>
<slot /> <!-- page content renders here -->
</main>
<footer>...</footer>
</body>
</html>
---
// src/pages/about.astro
import BaseLayout from '../layouts/BaseLayout.astro';
---
<BaseLayout title="About Us">
<h1>About Us</h1>
<p>Welcome to our company...</p>
</BaseLayout>
Enable SSR for dynamic pages by setting an adapter:
// astro.config.mjs
import { defineConfig } from 'astro/config';
import vercel from '@astrojs/vercel/serverless';
export default defineConfig({
output: 'hybrid', // 'static' | 'server' | 'hybrid'
adapter: vercel(),
});
Opt individual pages into SSR with export const prerender = false.
// src/pages/rss.xml.ts
import rss from '@astrojs/rss';
import { getCollection } from 'astro:content';
export async function GET(context) {
const posts = await getCollection('blog');
return rss({
title: 'My Blog',
description: 'Latest posts',
site: context.site,
items: posts.map(post => ({
title: post.data.title,
pubDate: post.data.date,
link: `/blog/${post.slug}/`,
})),
});
}
// src/pages/api/subscribe.ts
import type { APIRoute } from 'astro';
export const POST: APIRoute = async ({ request }) => {
const { email } = await request.json();
if (!email) {
return new Response(JSON.stringify({ error: 'Email required' }), {
status: 400,
headers: { 'Content-Type': 'application/json' },
});
}
await addToNewsletter(email);
return new Response(JSON.stringify({ success: true }), { status: 200 });
};
// src/components/SearchBox.tsx
import { useState } from 'react';
export default function SearchBox() {
const [query, setQuery] = useState('');
const [results, setResults] = useState([]);
async function search(e: React.FormEvent) {
e.preventDefault();
const data = await fetch(`/api/search?q=${query}`).then(r => r.json());
setResults(data);
}
return (
<form onSubmit={search}>
<input value={query} onChange={e => setQuery(e.target.value)} />
<button type="submit">Search</button>
<ul>{results.map(r => <li key={r.id}>{r.title}</li>)}</ul>
</form>
);
}
---
import SearchBox from '../components/SearchBox.tsx';
---
<!-- Hydrated immediately — this island is interactive -->
<SearchBox client:load />
.astro files — only hydrate what must be interactiveclient:visible over client:load for below-the-fold components to reduce initial JSimport.meta.env for enprojectnment variables — prefix public vars with PUBLIC_<ViewTransitions /> from astro:transitions for smooth page navigation without a full SPAclient:load on every component — this defeats Astro's performance advantage.astro frontmatter that gets used in client-facing templatesgetStaticPaths for dynamic routes in static mode — builds will fail.astro files runs server-side only and is never exposed to the browser.import.meta.env.PUBLIC_* only for non-sensitive values. Private env vars (no PUBLIC_ prefix) are never sent to the client.Astro.request inputs before database queries or API calls.set:html — it bypasses auto-escaping.Problem: JavaScript from a React/Vue component doesn't run in the browser
Solution: Add a client: directive (client:load, client:visible, etc.) — without it, components render as static HTML only.
Problem: getStaticPaths data is stale after content updates during dev
Solution: Astro's dev server watches content files — restart if changes to content/config.ts are not reflected.
Problem: Astro.props type is any — no autocomplete
Solution: Define a Props interface or type in the frontmatter and Astro will infer it automatically.
Problem: CSS from a .astro component bleeds into other components
Solution: Styles in .astro <style> tags are automatically scoped. Use :global() only when intentionally targeting children.
@sveltekit — When you need a full-stack framework with reactive UI (vs Astro's content focus)@nextjs-app-router-patterns — When you need a React-first full-stack framework@tailwind-patterns — Styling Astro sites with Tailwind CSS@progressive-web-app — Adding PWA capabilities to an Astro siteまだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Arquitecto de Soluciones Principal y Consultor Tecnológico de Andru.ia. Diagnostica y traza la hoja de ruta óptima para proyectos de IA en español.
日本語の概要は準備中です。原文の説明を表示しています。
Security audit, hardening, threat modeling (STRIDE/PASTA), Red/Blue Team, OWASP checks, code review, incident response, and infrastructure security for any project.
日本語の概要は準備中です。原文の説明を表示しています。
Ingeniero de Sistemas de Andru.ia. Diseña, redacta y despliega nuevas habilidades (skills) dentro del repositorio siguiendo el Estándar de Diamante.
日本語の概要は準備中です。原文の説明を表示しています。
Estratega de Inteligencia de Dominio de Andru.ia. Analiza el nicho específico de un proyecto para inyectar conocimientos, regulaciones y estándares únicos del sector. Actívalo tras definir el nicho.
日本語の概要は準備中です。原文の説明を表示しています。
AI-powered presentation generation via the 2slides API — create slides from text, match a reference image style, summarize documents into decks, add AI voice narration, and export pages/audio. Use for any "make slides", "create a deck", or "slides from this document" request.
日本語の概要は準備中です。原文の説明を表示しています。
Expert in building 3D experiences for the web - Three.js, React Three Fiber, Spline, WebGL, and interactive 3D scenes. Covers product configurators, 3D portfolios, immersive websites, and bringing depth to web experiences.
日本語の概要は準備中です。原文の説明を表示しています。