The config file
src/config/site.ts exports a single siteConfig object. It is fully typed and every field has a doc comment, so your editor shows what each one expects.
export const siteConfig: SiteConfig = { name: '@samortega', // header + title suffix title: 'Sam Ortega', // homepage <title> description: '…', // default meta description url: 'https://example.com', // production URL, no trailing slash locale: 'en_US', // …};Author & hero
author: { name: 'Sam Ortega', email: 'hello@example.com', // null hides the email everywhere avatar: '/images/avatar.svg', // structured data only jobTitle: 'Platform Engineer', headline: 'Making infrastructure boring,\none rollout at a time.', facts: [ { label: 'edu', value: "[Northfield Tech](https://example.com) '24" }, { label: 'prev', value: '[Halcyon](https://example.com) · platform' }, ], keywords: ['platform', 'sre', 'kubernetes'], resume: 'https://example.com/resume.pdf', // also served at /resume},headline—\nforces a line break on wide screens; on phones it wraps naturally.facts— the mono key–value block beside your name. Values accept inline Markdown links,codeand bold. An empty array hides the block.keywords— the lowercase, dot-separated row under the hero.resume— adds a “resume” link to the hero and footer, and a redirect at/resumeso you can share<your-domain>/resume.
Social links
social: [ { name: 'GitHub', icon: 'github', href: 'https://github.com/…' }, { name: 'LinkedIn', icon: 'linkedin', href: 'https://www.linkedin.com/in/…' },],Icons appear in the footer; the lowercase name appears in the hero’s link row. Available icons: github, gitlab, linkedin, twitter, bluesky, mastodon, threads, instagram, youtube, twitch, tiktok, discord, telegram, whatsapp, reddit, medium, substack, dribbble, behance, codepen, stackoverflow, spotify, pinterest, facebook, globe, mail, rss.
Navigation
navigation: [ { label: 'Posts', href: '/posts' }, { label: 'CV', href: 'https://example.com/cv.pdf' },],Internal paths are prefixed with the base path automatically; absolute URLs open in a new tab.
Homepage sections
home: { recentPosts: 6, // 0 hides "writing" featuredProjects: 4, // 0 hides "projects"},experience: [ { when, org, role, url, detail }, … ], // [] hides the sectionopenSource: { contributions: [ { title, repo, url }, … ], // [] hides the section githubUser: null, // set to fetch your merged-PR count at build time mergedCount: 42, // fallback / fixed count allUrl: null, // link for the count; derived from githubUser when null},Featured projects are those with featured: true in their frontmatter; when none are marked, the first projects by order are used.
Posts
posts: { rssFullContent: true, // include rendered HTML in /rss.xml groupByYear: true, // year labels on the posts index},Scenes
scenes: { default: 'matte', options: [ { id: 'matte', label: 'matte', wallpaper: '/images/scenes/matte.webp', scheme: 'dark', base: '#141416', accent: '#a8a3f7', dim: 0.32, }, // … ],},See Scenes & colours for what each field does and how to make your own.
Footer, demo mode & analytics
footer: { since: 2023, text: null, credit: true },theme: { purchaseUrl: null, purchaseLabel: 'Get this theme' },analytics: { cloudflareToken: null, // Cloudflare Web Analytics googleAnalyticsId: null, // GA4 measurement id},notFound: { title: 'Page not found', message: "This pod has been evicted. Let's reschedule you somewhere healthy.",},since sets the first year of the copyright range and text adds a line after it (a licence notice, say). theme.purchaseUrl is for the theme’s own demo site — when set it adds a small button to the header; leave it null on your site.
Feature flags
features: { posts: true, projects: true, docs: true, tags: true, sceneSwitcher: true, // header menu + `t` key (needs ≥ 2 scenes) readingProgress: true, // accent bar at the top of posts backToTop: true, edgeFades: true, // scrims at the viewport edges copyEmail: true, // email links copy the address viewTransitions: true, // cross-page fades (CSS only) footer: true,},Turning a section off removes its routes from the build, the sitemap, the RSS feed and the header navigation. The index pages live at src/pages/<section>/_index.astro and are injected by the small sections integration in astro.config.ts only when their flag is on; the dynamic routes next to them return no paths.