A fully static Astro + Svelte site using content from an atproto repository

README.md

tynanpurdy.com #

A personal website entirely powered by the AT Protocol. All content is stored as AT Protocol records and automatically displayed on the site without requiring manual rebuilds.

Features #

  • ✅ AT Protocol Native: All content comes from AT Protocol records
  • ✅ Blog System: Write blog posts as AT Proto records with Bluesky comments integration
  • ✅ Standard.site Integration: Automatically display publications and documents
  • ✅ Guestbook: Visitors can sign with their Bluesky accounts
  • ✅ OAuth Authentication: Secure user interactions via AT Protocol OAuth
  • ✅ Web Components: Lightweight, reusable UI components
  • ✅ Universal CSS System: Consistent styling with CSS custom properties
  • 🚧 Live Updates: Real-time content updates (using Astro experimental features)

Tech Stack #

  • Framework: Astro
  • Protocol: AT Protocol
  • Styling: CSS + Web Components
  • Authentication: AT Protocol OAuth
  • Package Manager: pnpm
  • Development Environment: Nix flakes

Getting Started #

Prerequisites #

  • Nix with flakes enabled

Setup #

  1. Clone the repository and enter the directory

  2. Activate the Nix development environment:

    nix develop
    

    Or use direnv for automatic activation:

    direnv allow
    
  3. Install dependencies:

    pnpm install
    
  4. Configure your AT Protocol identity:

    cp .env.example .env
    

    Edit .env and add your:

    • PUBLIC_ATPROTO_DID: Your DID (e.g., did:plc:...)
    • PUBLIC_ATPROTO_HANDLE: Your handle (e.g., you.bsky.social)
    • PUBLIC_ATPROTO_NAMESPACE: Your custom namespace (e.g., com.yourname)
    • OAuth credentials (for user interactions)
  5. Update the configuration in src/lib/atproto.ts:

    export const SITE_CONFIG: ATProtoConfig = {
      did: 'your-did-here',
      handle: 'your-handle.bsky.social',
    };
    
  6. Start the development server:

    pnpm dev
    
  7. Visit http://localhost:4321

Project Structure #

/
├── src/
│   ├── components/       # Web Components
│   │   ├── avatar.ts
│   │   ├── button.ts
│   │   └── card.ts
│   ├── layouts/          # Page layouts
│   │   └── BaseLayout.astro
│   ├── lib/              # Utility functions
│   │   ├── atproto.ts   # AT Protocol API wrappers
│   │   ├── blog.ts      # Blog functionality
│   │   ├── guestbook.ts # Guestbook functionality
│   │   └── oauth.ts     # OAuth authentication
│   ├── pages/            # Routes
│   │   ├── blog/
│   │   │   ├── index.astro
│   │   │   └── [slug].astro
│   │   ├── oauth/
│   │   │   └── callback.astro
│   │   ├── guestbook.astro
│   │   ├── index.astro
│   │   └── publications.astro
│   └── styles/
│       └── global.css    # Universal design system
├── public/               # Static assets
├── astro.config.mjs     # Astro configuration
├── flake.nix            # Nix development environment
└── package.json

Creating Content #

Blog Posts #

Create blog post records in your AT Protocol repository using the collection:

{namespace}.blog.post

Example record structure:

{
  "$type": "com.tynanpurdy.blog.post",
  "title": "My First Post",
  "text": "Post content here...",
  "tags": ["atproto", "blog"],
  "blueskyUri": "at://did:plc:.../app.bsky.feed.post/...",
  "createdAt": "2026-02-13T00:00:00.000Z"
}

The blueskyUri field links to a Bluesky post for comments and engagement.

Guestbook Entries #

Guestbook entries are automatically created when users sign via OAuth. They use the collection:

{namespace}.guestbook.entry

Publications #

Standard.site publications are automatically fetched from:

pub.standard.publication
pub.standard.document

Customization #

Styling #

Edit src/styles/global.css to customize the design system. All colors, spacing, typography, and other design tokens are defined as CSS custom properties at the root level.

Components #

Web Components are defined in src/components/. They use Shadow DOM and CSS custom properties for styling.

AT Protocol Collections #

Update the namespace in .env and throughout the codebase to use your own custom collections.

Building for Production #

pnpm build

The built site will be in the dist/ directory.

Roadmap #

Resources #

License #

MIT