Global Context
The Global Context is a powerful feature that makes data available to all components, includes, and autohandlers in the request chain.
What is Global Context?
Every request creates a GlobalContext object that travels through the entire request pipeline. All components in the chain (autohandlers, dhandlers, includes) share this same context.
Built-in Context Variables
The framework automatically provides these variables to every component:
$context - The Full Context Object
Component Path: /data/embedded-apps/pages/demo/context.html
Dhandler Path: N/A
Autohandlers: 1 active
$req - Request Information
Method: GET
URL: /demo/context.html
Path: /demo/context.html
User-Agent: Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; [email protected])
IP Address: 104.23.243.32
$res - Response Object
The response object allows you to control the HTTP response:
<%
// Set custom headers
$res.setHeader('X-Custom-Header', 'value');
// Set status code
$res.status(200);
// Redirect
// $res.redirect('/other-page');
// Send JSON
// $res.json({ data: 'value' });
%>
$session - Session Data
Your Current Session:
Session ID: 1ZxpWg4jHi8O8lGP2w-7YCBHFL9Nj03I
Visit Count: 0
Last Visit: First visit
$env - Environment Variables
NODE_ENV: production
Platform: linux
$cache - Cache Manager
Access the caching system:
<%
// Get from cache
const cached = await $cache.get('mykey');
// Set in cache (key, value, ttl in seconds)
await $cache.set('mykey', 'myvalue', 3600);
// Remember pattern
const data = await $cache.remember('expensive', 600, async () => {
return await fetchExpensiveData();
});
%>
$db - Database Handle
If database is configured, access it via:
<%
if ($db) {
// Execute query
const results = await $db.query('SELECT * FROM users WHERE id = $1', [123]);
// Get connection
const conn = await $db.getConnection();
// Use connection...
conn.release();
}
%>
Custom Context Data
You can store and retrieve custom data in the context:
Setting Data
<%
// Set custom data
$context.set('myKey', 'myValue');
// Set complex data
$context.set('userInfo', {
name: 'John Doe',
role: 'admin'
});
%>
Getting Data
<%
// Get custom data
const value = $context.get('myKey');
const user = $context.get('userInfo');
// Check if exists
if ($context.has('myKey')) {
// ...
}
%>
Example: Custom Data Set by This Component
Message: This was set by the component!
Timestamp: 2025-12-26T10:49:04.953Z
Context Flow
The context flows through the request pipeline:
1. Request arrives → GlobalContext created
2. Middleware runs → Attaches $db, $cache, $session
3. Autohandler 1 → Can set context data
4. Autohandler 2 → Can read/modify context data
5. Main Component → Can read/modify context data
6. Includes → Share same context
7. Response sent
Sharing Data Between Components
Use context to pass data from autohandlers to child components:
In Autohandler:
<%
// Set site-wide configuration
$context.set('siteConfig', {
siteName: 'My Awesome Site',
theme: 'dark',
version: '1.0.0'
});
// Set user information
$context.set('currentUser', $session.user);
%>
In Child Component:
<%
const config = $context.get('siteConfig');
const user = $context.get('currentUser');
%>
<h1><%= config.siteName %></h1>
<p>Welcome, <%= user?.name || 'Guest' %></p>
Context in Includes
Included components inherit the global context and can receive additional parameters:
<%# Include with shared context %>
<% await include('widget.html') %>
<%# Include with additional parameters %>
<% await include('widget.html', {
title: 'Custom Title',
data: localData
}) %>
In the included component:
<%
// Access global context
const sessionData = $session;
// Access passed parameters
const title = title || 'Default Title';
// Access shared custom data
const sharedData = $context.get('sharedKey');
%>
Utility Functions
The context also provides utility functions:
include(path, params)
<% await include('/shared/header.html') %>
<% await include('components/card.html', { title: 'Card' }) %>
escape(html)
<%
const userInput = '<script>alert("xss")</script>';
%>
Safe: <%= escape(userInput) %>
json(obj)
<%
const data = { key: 'value', number: 123 };
%>
<script>
const config = <%- json(data) %>;
</script>
Request Details Example
Complete information about the current request:
Request Details:
Method: GET
Path: /demo/context.html
URL: /demo/context.html
Query Parameters:
{}
Headers (partial):
Accept: */*
Content-Type: N/A
Context Info:
Component: /data/embedded-apps/pages/demo/context.html
Autohandlers: 1
Best Practices
- Use context for request-scoped data only (not for persistent storage)
- Set shared configuration in root autohandlers
- Use descriptive keys for custom data
- Check if data exists before using it
- Don't store large objects in context (use caching instead)
- Remember that context is shared across all components in a request
Advanced: Middleware Integration
The context is enhanced by middleware:
// In your app configuration
const app = new StoneJS({
root: './pages',
// Middleware adds to context
middleware: [
(req, res, next) => {
// Custom data available in $req
req.customData = 'Available in context!';
next();
}
]
});