Documentation
Platform Integration/Astro Integration

Astro Integration

Spyglasses integrates with Astro applications through server-side middleware. Follow these steps to set up Spyglasses in your Astro project.

Important: SSR Required

⚠️ Astro middleware only runs in Server-Side Rendering (SSR) mode. Before installing Spyglasses, ensure your Astro app is configured for SSR:

  1. Install a server adapter. Astro maintains official adapters for Node.js, Netlify, Vercel, and [Cloudflare]https://docs.astro.build/en/guides/integrations-guide/cloudflare/. You can find both official and community adapters in their integrations directory. Choose the one that corresponds to your deployment environment.
  2. Configure your astro.config.mjs with output: 'server' or output: 'hybrid'
  3. For hybrid mode, mark individual routes with export const prerender = false to enable SSR

Installation

  1. Install the package:

    npm install @spyglasses/astro

    with yarn:

    yarn add @spyglasses/astro

    with pnpm:

    pnpm add @spyglasses/astro
  2. Install a server adapter (if not already installed):

    For Node.js:

    npm install @astrojs/node

    For Vercel:

    npm install @astrojs/vercel

    For Netlify:

    npm install @astrojs/netlify
  3. Add your API key: Create or update your .env file with your Spyglasses API key:

    SPYGLASSES_API_KEY=your_api_key_here
    

Configuration

Step 1: Configure SSR in Astro

Update your astro.config.mjs to enable SSR:

// astro.config.mjs
import { defineConfig } from 'astro/config';
import node from '@astrojs/node';
 
export default defineConfig({
  output: 'server', // or 'hybrid'
  adapter: node({
    mode: 'standalone'
  }),
});

Step 2: Create Middleware

Create a src/middleware.ts (or .js) file with the Spyglasses middleware:

// src/middleware.ts
import { createSpyglassesMiddleware } from '@spyglasses/astro';
 
export const onRequest = createSpyglassesMiddleware({
  apiKey: process.env.SPYGLASSES_API_KEY,
  debug: process.env.SPYGLASSES_DEBUG === 'true'
});

Middleware Chaining

If you have existing middleware, you can chain it with Spyglasses using Astro's sequence function:

// src/middleware.ts
import { sequence } from 'astro:middleware';
import { createSpyglassesMiddleware } from '@spyglasses/astro';
 
const spy = createSpyglassesMiddleware({
  apiKey: process.env.SPYGLASSES_API_KEY,
  debug: process.env.SPYGLASSES_DEBUG === 'true'
});
 
async function customAuthMiddleware(context: any, next: () => Promise<Response>) {
  // Your custom middleware logic
  console.log('Request URL:', context.url.pathname);
  return next();
}
 
async function customLoggingMiddleware(context: any, next: () => Promise<Response>) {
  // More custom logic
  const response = await next();
  console.log('Response status:', response.status);
  return response;
}
 
// Chain middleware - Spyglasses runs first
export const onRequest = sequence(
  spy as any,
  customAuthMiddleware as any,
  customLoggingMiddleware as any
);

Configuration Options

The createSpyglassesMiddleware function accepts these configuration options:

OptionTypeRequiredDescriptionDefault
apiKeystringYesYour Spyglasses API key-
debugbooleanNoEnable debug loggingfalse
collectorEndpointstringNoCustom collector endpointSpyglasses default
excludePathsstring[]NoPaths to exclude from monitoring[]

Advanced Configuration

// src/middleware.ts
import { createSpyglassesMiddleware } from '@spyglasses/astro';
 
export const onRequest = createSpyglassesMiddleware({
  apiKey: process.env.SPYGLASSES_API_KEY,
  debug: process.env.NODE_ENV === 'development',
  collectorEndpoint: process.env.SPYGLASSES_COLLECTOR_ENDPOINT,
  excludePaths: [
    '/admin',
    '/api/internal',
    '/_astro/', // Exclude Astro internal routes
  ],
});

SSR Modes

Astro supports three rendering modes. Spyglasses works with:

All pages are rendered on-demand:

// astro.config.mjs
export default defineConfig({
  output: 'server',
  adapter: node()
});

Hybrid Mode

Most pages are pre-rendered, but you can opt specific pages into SSR:

// astro.config.mjs
export default defineConfig({
  output: 'hybrid',
  adapter: node()
});

Then in pages where you want Spyglasses to run:

---
// src/pages/blog/[slug].astro
export const prerender = false; // Enable SSR for this page
---
 
<html>
  <!-- Your page content -->
</html>

Static Mode (Not Supported)

⚠️ Spyglasses does not work with fully static builds (output: 'static') because middleware only runs at build time, not at request time.

Adapters

Spyglasses works with all Astro server adapters:

Node.js

// astro.config.mjs
import node from '@astrojs/node';
 
export default defineConfig({
  output: 'server',
  adapter: node({
    mode: 'standalone'
  })
});

Vercel

// astro.config.mjs
import vercel from '@astrojs/vercel/serverless';
 
export default defineConfig({
  output: 'server',
  adapter: vercel()
});

Netlify

// astro.config.mjs
import netlify from '@astrojs/netlify';
 
export default defineConfig({
  output: 'server',
  adapter: netlify()
});

Cloudflare

// astro.config.mjs
import cloudflare from '@astrojs/cloudflare';
 
export default defineConfig({
  output: 'server',
  adapter: cloudflare()
});

Docker

If you deploy with Docker, set your API key in your Dockerfile or docker-compose:

Dockerfile:

ENV SPYGLASSES_API_KEY=your_api_key_here

docker-compose:

services:
  web:
    environment:
      - SPYGLASSES_API_KEY=your_api_key_here

Deployment

When deploying your Astro application, make sure to add your Spyglasses API key to your environment variables:

Vercel

  1. Go to Project Settings > Environment Variables
  2. Add SPYGLASSES_API_KEY
  3. Ensure you're using the Vercel adapter in astro.config.mjs
  4. Deploy to apply changes

Netlify

  1. Go to Site Settings > Build & Deploy > Environment
  2. Add SPYGLASSES_API_KEY
  3. Ensure you're using the Netlify adapter in astro.config.mjs
  4. Trigger a new deploy

Cloudflare Pages

  1. Go to Workers & Pages > Your Project > Settings > Environment Variables
  2. Add SPYGLASSES_API_KEY
  3. Ensure you're using the Cloudflare adapter
  4. Redeploy your application

Node.js Deployment

For self-hosted Node.js deployments:

export SPYGLASSES_API_KEY=your_api_key_here
npm run build
node ./dist/server/entry.mjs

Railway

  1. Add environment variables in your Railway dashboard
  2. Add SPYGLASSES_API_KEY
  3. Trigger a new deployment

Verifying Installation

After deploying your application with Spyglasses:

  1. Check server logs for Spyglasses initialization (if debug enabled)
  2. Test SSR is working: View page source - if you see full HTML, SSR is working
  3. Monitor your dashboard at spyglasses.io for incoming data
  4. Test with a bot user agent:
    curl -H "User-Agent: GPTBot/1.0" https://yoursite.com/

Troubleshooting

Middleware Not Running

Most Common Issue: Astro is in static mode or page is pre-rendered

  • Verify output: 'server' or output: 'hybrid' in astro.config.mjs
  • For hybrid mode, check pages have export const prerender = false
  • Ensure you have a server adapter installed and configured
  • Check that middleware file is at src/middleware.ts or src/middleware.js

API Key Not Found

  • Verify environment variable is set: SPYGLASSES_API_KEY
  • Check for typos in variable name
  • Ensure deployment includes environment variables
  • For local development, check .env file exists and is not in .gitignore

No Data in Dashboard

  • Verify your API key is correct
  • Enable debug mode to see detection logs
  • Check server console for errors
  • Ensure pages are actually using SSR (not pre-rendered)

Build Errors

  • Ensure you have a server adapter installed: npm install @astrojs/node
  • Check Astro version compatibility (4.0.0 or higher recommended)
  • Verify middleware file syntax is correct

TypeScript Errors

If you see TypeScript errors with the middleware:

// src/middleware.ts
import { sequence } from 'astro:middleware';
import type { MiddlewareHandler } from 'astro';
import { createSpyglassesMiddleware } from '@spyglasses/astro';
 
const spy = createSpyglassesMiddleware({
  apiKey: process.env.SPYGLASSES_API_KEY,
}) as MiddlewareHandler;
 
export const onRequest = spy;

Performance Issues

  • Enable debug mode to check for errors
  • Verify excludePaths configuration
  • Check network latency to collector endpoint
  • Monitor server response times

Adapter-Specific Issues

  • Vercel: Ensure you're using @astrojs/vercel/serverless or @astrojs/vercel/edge
  • Netlify: Ensure you're using @astrojs/netlify (not @astrojs/netlify/static)
  • Cloudflare: Edge runtime has some limitations - test thoroughly
  • Node.js: Ensure Node version is 18.0.0 or higher

Example Project Structure

Here's a complete example of a working Astro + Spyglasses setup:

my-astro-site/
├── src/
│   ├── middleware.ts          # Spyglasses middleware
│   ├── pages/
│   │   ├── index.astro        # SSR page
│   │   └── blog/
│   │       └── [slug].astro   # SSR blog posts
│   └── layouts/
│       └── Layout.astro
├── .env                        # Environment variables
├── astro.config.mjs           # Astro config with adapter
└── package.json

src/middleware.ts:

import { createSpyglassesMiddleware } from '@spyglasses/astro';
 
export const onRequest = createSpyglassesMiddleware({
  apiKey: process.env.SPYGLASSES_API_KEY,
  debug: true
});

astro.config.mjs:

import { defineConfig } from 'astro/config';
import node from '@astrojs/node';
 
export default defineConfig({
  output: 'server',
  adapter: node({ mode: 'standalone' })
});

.env:

SPYGLASSES_API_KEY=your_api_key_here

Need help? Contact support@spyglasses.io