CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-astrojs--node

Node.js adapter for Astro framework enabling server-side rendering and standalone server deployments

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

handlers.mddocs/

Request Handlers

Handler creation functions for different deployment modes including middleware, standalone, application rendering, and static file serving.

Capabilities

Middleware Handler

Creates Express/Connect compatible middleware with error handling for integration with existing Node.js servers.

/**
 * Creates middleware compatible with Express, Connect, and similar frameworks
 * Supports both normal middleware and error middleware patterns
 * @param app - NodeApp instance for rendering Astro pages
 * @param options - Resolved adapter options including mode and paths
 * @returns RequestHandler function compatible with Express middleware
 */
function createMiddleware(app: NodeApp, options: Options): RequestHandler;

type RequestHandler = (
  req: IncomingMessage,
  res: ServerResponse,
  next?: (err?: unknown) => void,
  locals?: object
) => void | Promise<void>;

Usage Examples:

import express from "express";
import { NodeApp } from "astro/app/node";
import { createExports } from "@astrojs/node/server.js";

const app = express();
const astroApp = new NodeApp(manifest);
const { handler: astroHandler } = createExports(manifest, options);

// Mount Astro as middleware
app.use(astroHandler);

// Other Express routes can be added
app.get("/api/health", (req, res) => {
  res.json({ status: "ok" });
});

app.listen(3000);

Error Handling Features:

  • Supports Express error middleware pattern (4-parameter function)
  • Catches rendering errors and sends 500 response
  • Logs errors using Astro's logger
  • Respects Express next() callback for error delegation

Standalone Handler

Creates complete request handler for standalone mode combining static file serving with SSR rendering.

/**
 * Creates standalone request handler combining static and app handlers
 * Validates request URLs and routes to appropriate handler
 * @param app - NodeApp instance for SSR rendering
 * @param options - Resolved adapter options including client paths
 * @returns Complete request handler for http.createServer
 */
function createStandaloneHandler(
  app: NodeApp, 
  options: Options
): (req: http.IncomingMessage, res: http.ServerResponse) => void;

Usage Examples:

import http from "http";
import { NodeApp } from "astro/app/node";
import { createExports } from "@astrojs/node/server.js";

const app = new NodeApp(manifest);
const { handler } = createExports(manifest, options);

const server = http.createServer(handler);
server.listen(8080, "localhost");

Request Processing:

  1. Validates request URL (decodes URI, sends 400 for malformed URLs)
  2. Attempts static file serving first
  3. Falls back to SSR rendering for dynamic routes
  4. Handles all errors gracefully with appropriate HTTP status codes

Application Handler

Creates Node.js request handler specifically for on-demand rendered pages with error tracking and unhandled rejection monitoring.

/**
 * Creates handler for on-demand rendered pages with AsyncLocalStorage tracking
 * Compatible with http.createServer and Connect middleware
 * @param app - NodeApp instance for page rendering
 * @param options - Resolved adapter options including error page host
 * @returns RequestHandler for SSR page rendering
 */
function createAppHandler(app: NodeApp, options: Options): RequestHandler;

Advanced Features:

  • AsyncLocalStorage Integration: Tracks current request URL for error logging
  • Unhandled Rejection Monitoring: Logs unhandled promise rejections with request context
  • Error Page Fetching: Supports fetching prerendered error pages from external hosts
  • Route Matching: Intelligent routing with fallback to 404 handling

Usage Examples:

// Note: createAppHandler is not directly exported, use createExports instead
import { createExports } from "@astrojs/node/server.js";

const { handler: appHandler } = createExports(manifest, {
  ...options,
  experimentalErrorPageHost: "https://cdn.example.com"
});

// Use with custom server
const server = http.createServer(appHandler);

Error Page Host Configuration:

const prerenderedErrorPageFetch = originUrl
  ? (url: string) => {
      const errorPageUrl = new URL(url);
      errorPageUrl.protocol = originUrl.protocol;
      errorPageUrl.host = originUrl.host;
      return fetch(errorPageUrl);
    }
  : undefined;

Static File Handler

Creates handler for static files and prerendered pages with caching, trailing slash handling, and header support.

/**
 * Creates handler for static files and prerendered pages
 * Handles trailing slash redirects, caching headers, and static header injection
 * @param app - NodeApp instance for route matching and base path handling
 * @param options - Resolved adapter options including client path and assets
 * @returns Static file handler with SSR fallback capability
 */
function createStaticHandler(
  app: NodeApp, 
  options: Options
): (req: IncomingMessage, res: ServerResponse, ssr: () => unknown) => void;

Key Features:

  • Trailing Slash Handling: Configurable 301 redirects based on trailingSlash option
  • Immutable Caching: Far-future caching headers for hashed assets in _astro/ directory
  • Static Headers: Injects experimental static headers for prerendered pages
  • Directory Index: Automatic index.html serving for directories
  • Security: Allows .well-known/ files, denies other dotfiles

Usage Examples:

// Note: createStaticHandler is not directly exported, it's used internally
// For static file handling, use the standalone handler from createExports:
import { createExports } from "@astrojs/node/server.js";

const { handler } = createExports(manifest, options); // Includes static handling

// The handler automatically handles static files and falls back to SSR
http.createServer(handler).listen(8080);

Trailing Slash Behavior:

interface TrailingSlashOptions {
  /** Never allow trailing slashes - redirect to remove them */
  'never': '301 redirect from /path/ to /path';
  /** Always require trailing slashes - redirect to add them */  
  'always': '301 redirect from /path to /path/';
  /** Ignore trailing slashes - serve content for both */
  'ignore': 'serve /path/index.html for both /path and /path/';
}

Caching Headers:

  • Hashed Assets (/_astro/*): Cache-Control: public, max-age=31536000, immutable
  • Other Static Files: Default send library caching behavior
  • Prerendered Pages: No special caching headers (use Astro's configuration)

Handler Integration Patterns

Express Integration

import express from "express";
import { createMiddleware } from "@astrojs/node";

const app = express();

// Serve static files from public directory
app.use(express.static("public"));

// Mount Astro middleware
app.use(createMiddleware(astroApp, options));

// API routes after Astro
app.use("/api", apiRouter);

app.listen(3000);

Custom Server Integration

import http from "http";
import { createAppHandler, createStaticHandler } from "@astrojs/node";

const appHandler = createAppHandler(app, options);
const staticHandler = createStaticHandler(app, options);

const server = http.createServer((req, res) => {
  // Custom logic before handlers
  if (req.url.startsWith("/health")) {
    res.writeHead(200);
    res.end("OK");
    return;
  }

  // Static files first, then SSR
  staticHandler(req, res, () => appHandler(req, res));
});

Middleware Chain with Error Handling

import express from "express";

const app = express();

// Request logging
app.use((req, res, next) => {
  console.log(`${req.method} ${req.url}`);
  next();
});

// Astro handler
app.use(createMiddleware(astroApp, options));

// Error handling middleware
app.use((err, req, res, next) => {
  console.error("Server error:", err);
  res.status(500).send("Internal Server Error");
});

Error Handling

All handlers include comprehensive error handling:

Middleware Handler Errors

  • Rendering Errors: Caught and logged, 500 response sent if headers not sent
  • Error Middleware: Supports Express 4-parameter error middleware pattern
  • Next Callback: Properly delegates errors using next(error)

Standalone Handler Errors

  • URL Validation: Malformed URLs return 400 Bad Request
  • Static File Errors: Gracefully fall back to SSR rendering
  • SSR Errors: Logged with request context, appropriate error response

App Handler Errors

  • Request Creation: Invalid requests get 500 Internal Server Error
  • Unhandled Rejections: Logged with current request URL context
  • Route Errors: Proper error page rendering with external fetch support

Static Handler Errors

  • File System Errors: Fall back to SSR rendering
  • Send Library Errors: Handled by send library with appropriate status codes
  • Headers JSON Errors: Logged but don't prevent serving

docs

handlers.md

index.md

integration.md

preview.md

server-management.md

server-runtime.md

tile.json