AbsoluteJS

HTML

Build HTML pages with automatic asset bundling and raw out-of-order streaming support.

#Build Configuration

Add HTML to your build by specifying the directory containing your HTML files:

TS
const manifest = await build({
  htmlDirectory: 'src/frontend'
});

// The manifest maps page names to their built HTML files
// { "home": "/build/pages/home.html", "about": "/build/pages/about.html" }

#Page Handler

Pass the path to the built HTML file to handleHTMLPageRequest:

TS
// backend/server.ts
import { handleHTMLPageRequest } from '@absolutejs/absolute';

new Elysia()
  .get('/', () =>
    handleHTMLPageRequest('./build/pages/home.html')
  )
  .get('/about', () =>
    handleHTMLPageRequest('./build/pages/about.html')
  )

#How It Works

Write your HTML with relative paths to your scripts and stylesheets:

HTML
<!-- src/html/pages/home.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <title>My App</title>
  <link rel="stylesheet" href="./styles/main.css">
</head>
<body>
  <h1>Welcome</h1>
  <div id="app"></div>

  <script src="./scripts/app.ts"></script>
</body>
</html>

During the build process, AbsoluteJS detects all referenced assets, bundles them, and rewrites the paths to point to the built files:

HTML
<!-- After build, paths are automatically updated -->
<!DOCTYPE html>
<html lang="en">
<head>
  <title>My App</title>
  <link rel="stylesheet" href="/build/main-a3f2c1.css">
</head>
<body>
  <h1>Welcome</h1>
  <div id="app"></div>

  <script src="/build/app-b7d4e9.js"></script>
</body>
</html>

#Asset Detection

The build system automatically detects and processes assets referenced in your HTML:

JavaScript

.js files are bundled and minified

TypeScript

.ts files are compiled to JS and bundled

CSS

.css files are bundled and minified

HTML
// The build system automatically detects and processes:

// JavaScript files
<script src="./scripts/app.js"></script>

// TypeScript files (compiled to JS)
<script src="./scripts/app.ts"></script>

// CSS files
<link rel="stylesheet" href="./styles/main.css">

// All paths are updated to point to the bundled, hashed files
Hashed filenamesBuilt files include content hashes for cache busting
Path rewritingAll asset paths are automatically updated to the build output
BundlingAssets are optimized and minified for production

#Out-of-Order Streaming

HTML uses the raw streaming transport directly, and the server stays explicit: pass streamingSlots to handleHTMLPageRequest while the document renders stable fallback placeholders.

HTML
<main>
  <h1>Reports</h1>

  <div id="report-summary" data-absolute-slot="true">
    <div class="card-skeleton">Loading summary...</div>
  </div>

  <div id="report-feed" data-absolute-slot="true">
    <div class="card-skeleton">Loading activity...</div>
  </div>
</main>

The route passes the explicit streaming slot definitions:

TS
app.get('/reports', () =>
  handleHTMLPageRequest(asset(manifest, 'ReportsHTML'), {
    streamingSlots: [
      {
        id: 'report-summary',
        resolve: async () => renderSummaryHtml(await getSummary())
      },
      {
        id: 'report-feed',
        resolve: async () => renderFeedHtml(await getActivityFeed())
      }
    ]
  })
);