AbsoluteJS

Error Boundaries

Convention-based error and not-found pages that activate automatically. Drop a file, get resilient error handling.

#How It Works

AbsoluteJS uses a file convention to detect error and not-found pages. During the build, it scans your pages directories for files matching the convention patterns. At runtime, when SSR throws an error, AbsoluteJS catches it and renders the matching error convention component instead of crashing.

Auto-detectionthe build scans for error.tsx, *.error.tsx, not-found.tsx, and the universal error.html / not-found.html fallbacks
Typed render contractpage components receive a flat ErrorPageProps shape (name, message, optional stack). Helper functions defineRenderErrorPage and defineRenderNotFoundPage type the return as a real HTML document
SSR catchwhen a page throws during server-side rendering, the error is caught and the matching convention component receives the typed props
Client hydrationthe error page hydrates on the client just like any other page

#Convention Files

Place these files alongside your page components. The naming pattern tells AbsoluteJS what each file does:

BASH
src/frontend/react/pages/
  Home.tsx
  Home.error.tsx     # page-specific error boundary for Home
  About.tsx
  error.tsx          # default error page for all React pages
  not-found.tsx      # 404 page
  error.html         # universal HTML fallback (any framework, zero config)
  not-found.html     # universal 404 fallback
error.tsxdefault error page for all pages in that framework directory
Page.error.tsxpage-specific error boundary that overrides the default for that page only
not-found.tsxcustom 404 page rendered when no route matches
error.htmluniversal HTML fallback shared across frameworks. Tokens {{name}}, {{message}}, and {{stack}} are replaced server-side
not-found.htmluniversal 404 fallback for any framework

#Error Pages

An error convention component receives a flat ErrorPageProps object — { name, message, stack? }, a serializable subset of Error. Here is a React example:

TSX
// src/frontend/react/pages/error.tsx
import type { ErrorPageProps } from '@absolutejs/absolute';

export const ErrorPage = ({ name, message, stack }: ErrorPageProps) => {
  return (
    <div style={{ padding: '2rem', fontFamily: 'system-ui' }}>
      <h1>{name}: Something went wrong</h1>
      <p>{message}</p>
      {stack && (
        <pre style={{ whiteSpace: 'pre-wrap', opacity: 0.7 }}>
          {stack}
        </pre>
      )}
    </div>
  );
};

The shape is Pick<Error, "name" | "message" | "stack">. In production stack is omitted; in development the full stack trace is included for debugging.

#Page-Specific Errors

Name an error file after the page it belongs to. For example, Home.error.tsx only activates when Home.tsx throws. This lets you show different error UI per page while keeping a generic fallback.

BASH
src/frontend/react/pages/
  Home.tsx              # the page component
  Home.error.tsx        # error boundary ONLY for Home
  Dashboard.tsx         # another page
  Dashboard.error.tsx   # error boundary ONLY for Dashboard
  error.tsx             # fallback for pages without a specific error file

#Not-Found Pages

The not-found.tsx convention file handles 404 responses. When a request hits a route that does not exist, AbsoluteJS renders this component with a 404 status code.

TSX
// src/frontend/react/pages/not-found.tsx
export const NotFound = () => {
  return (
    <div style={{ padding: '2rem', fontFamily: 'system-ui', textAlign: 'center' }}>
      <h1>404</h1>
      <p>The page you're looking for doesn't exist.</p>
      <a href="/">Go home</a>
    </div>
  );
};

For function-style not-found pages (Angular, plain HTML-string renderers), use defineRenderNotFoundPage. The helper types the return as a real HTML document — the string must start with <!DOCTYPE html>:

TS
// src/frontend/angular/pages/not-found.ts
import { defineRenderNotFoundPage } from '@absolutejs/absolute';

export default defineRenderNotFoundPage(() => `<!DOCTYPE html>
<html>
  <body style="padding: 2rem; font-family: system-ui; text-align: center;">
    <h1>404</h1>
    <p>The page you're looking for doesn't exist.</p>
    <a href="/">Go home</a>
  </body>
</html>`);

#Universal HTML Fallback

Drop an error.html into any configured framework's pages directory — no extra config flag, no dedicated dir. Any framework that fails to render its own error page falls through to it. Tokens are replaced server-side from the thrown Error: {{name}}, {{message}}, {{stack}} (HTML-escaped; stack blanks in production).

HTML
<!-- drop in any pages dir, e.g. src/frontend/react/pages/error.html -->
<!DOCTYPE html>
<html>
  <body style="padding: 2rem; font-family: system-ui;">
    <h1>{{name}}: Something went wrong</h1>
    <p>{{message}}</p>
    <pre style="white-space: pre-wrap; opacity: 0.7;">{{stack}}</pre>
  </body>
</html>

The not-found.html equivalent is the project-wide 404 fallback when no framework registers its own.

#Fallback Chain

When an error occurs, AbsoluteJS resolves the error page using a priority chain. The most specific match wins:

BASH
Error Fallback Chain (highest to lowest priority):

1. Page-specific error file  Home.error.tsx  (only for Home page)
2. Framework default error  error.tsx       (for all pages in that framework)
3. Universal HTML fallback  error.html      (any framework, token-replaced)
4. Generic SSR error page  ssrErrorPage()  (built-in last resort)

If no convention file exists at any level, AbsoluteJS falls back to its built-in ssrErrorPage() which renders a minimal error screen.

#Multi-Framework

Error conventions work across all supported frameworks. Each framework uses its own syntax but follows the same file naming pattern and receives the same flat ErrorPageProps shape.

#Svelte

SVELTE
<!-- src/frontend/svelte/pages/error.svelte -->
<script lang="ts">
  import type { ErrorPageProps } from '@absolutejs/absolute';
  let { name, message, stack }: ErrorPageProps = $props();
</script>

<div style="padding: 2rem; font-family: system-ui;">
  <h1>{name}: Something went wrong</h1>
  <p>{message}</p>
  {#if stack}
    <pre style="white-space: pre-wrap; opacity: 0.7;">{stack}</pre>
  {/if}
</div>

#Vue

HTML
<!-- src/frontend/vue/pages/error.vue -->
<script setup lang="ts">
import type { ErrorPageProps } from '@absolutejs/absolute';
defineProps<ErrorPageProps>();
</script>

<template>
  <div style="padding: 2rem; font-family: system-ui;">
    <h1>{{ name }}: Something went wrong</h1>
    <p>{{ message }}</p>
    <pre v-if="stack" style="white-space: pre-wrap; opacity: 0.7;">
      {{ stack }}
    </pre>
  </div>
</template>

#Angular

Angular convention error pages use the function-style defineRenderErrorPage helper. The helper types the return as a real HTML document so missing doctypes fail to type-check rather than slipping into runtime:

TS
// src/frontend/angular/pages/error.ts
import { defineRenderErrorPage } from '@absolutejs/absolute';

export default defineRenderErrorPage(({ name, message, stack }) => `<!DOCTYPE html>
<html>
  <body style="padding: 2rem; font-family: system-ui;">
    <h1>${name}: Something went wrong</h1>
    <p>${message}</p>
    ${stack ? `<pre style="white-space: pre-wrap; opacity: 0.7;">${stack}</pre>` : ''}
  </body>
</html>`);

#Example Project

See a full working example with error boundaries configured for multiple frameworks in the error-boundaries-example repository.