When rendering on the server, you can access request headers and cookies, and modify response headers, cookies, and status codes through the BuildContext extension.
These APIs are only available on the server. They will throw an error if called on the client.
Reading Request Data
Access HTTP headers from the current request with case-insensitive keys.
Map<String, String> get headers
If a header occurs more than once, they are concatenated with a comma.
Example:
Builder(
builder: (context) {
final userAgent = context.headers['user-agent'];
final acceptLanguage = context.headers['accept-language'];
return div([], [
text('User Agent: $userAgent'),
text('Language: $acceptLanguage'),
]);
},
)
Access HTTP headers with multiple values.
Map<String, List<String>> get headersAll
If a header occurs only once, its value is a singleton list. If a header occurs with no value, the empty string is used.
Example:
Builder(
builder: (context) {
final acceptHeaders = context.headersAll['accept'];
return div([], [
text('Accept headers: ${acceptHeaders?.join(", ")}'),
]);
},
)
cookies
Access cookies sent with the current request.
Map<String, String> get cookies
Example:
Builder(
builder: (context) {
final sessionId = context.cookies['session_id'];
final theme = context.cookies['theme'] ?? 'light';
return div([], [
text('Session: $sessionId'),
text('Theme: $theme'),
]);
},
)
url
Access the URL of the current request.
Example:
Builder(
builder: (context) {
final currentUrl = context.url;
return div([], [
text('Current URL: $currentUrl'),
]);
},
)
Modifying Response Data
Set a response header.
void setHeader(String name, String value)
Example:
Builder(
builder: (context) {
// Set custom headers
context.setHeader('X-Custom-Header', 'MyValue');
context.setHeader('Cache-Control', 'max-age=3600');
return div([], [text('Headers set!')]);
},
)
setCookie()
Set a cookie in the response.
void setCookie(
String name,
String value, {
DateTime? expires,
int? maxAge,
String? domain,
String? path,
bool secure = false,
bool httpOnly = true,
SameSite? sameSite,
})
The name of the cookie. Must be composed of valid characters according to RFC 6265.
The value of the cookie. Must be composed of valid characters according to RFC 6265.
The time at which the cookie expires.
The number of seconds until the cookie expires. A zero or negative value means the cookie has expired.
The domain that the cookie applies to.
The path within the domain that the cookie applies to.
Whether to only send this cookie on secure (HTTPS) connections.
Whether the cookie is only sent in HTTP requests and is not accessible to client-side scripts.
Controls whether the cookie is sent with cross-site requests. Values: SameSite.strict, SameSite.lax, or SameSite.none.
Example:
import 'dart:io'; // For SameSite
Builder(
builder: (context) {
// Set a simple cookie
context.setCookie('theme', 'dark');
// Set a cookie with options
context.setCookie(
'session_id',
'abc123xyz',
maxAge: 3600, // 1 hour
path: '/',
secure: true,
httpOnly: true,
sameSite: SameSite.strict,
);
// Set a cookie with expiration date
context.setCookie(
'remember_me',
'true',
expires: DateTime.now().add(Duration(days: 30)),
path: '/',
);
return div([], [text('Cookies set!')]);
},
)
setStatusCode()
Set the response status code.
void setStatusCode(int statusCode, {Object? responseBody})
The HTTP status code (e.g., 200, 404, 500).
Optional response body to send instead of the rendered HTML. Supported types are String and Uint8List.
Example:
Builder(
builder: (context) {
// Set a custom status code
context.setStatusCode(201);
return div([], [text('Created!')]);
},
)
Custom Response Body
You can override the rendered HTML and send a custom response:
import 'dart:convert';
Builder(
builder: (context) {
// Check if this is an API request
if (context.url.startsWith('/api/')) {
// Return JSON instead of HTML
context.setStatusCode(
200,
responseBody: jsonEncode({
'status': 'ok',
'data': {'message': 'Hello, API!'}
}),
);
context.setHeader('Content-Type', 'application/json');
}
return div([], [text('Normal HTML response')]);
},
)
Binary Response:
import 'dart:typed_data';
Builder(
builder: (context) {
if (context.url == '/image') {
final imageBytes = Uint8List.fromList([/* ... */]);
context.setStatusCode(200, responseBody: imageBytes);
context.setHeader('Content-Type', 'image/png');
}
return div([], [text('Page')]);
},
)
Complete Example
import 'dart:io';
import 'package:jaspr/jaspr.dart';
class AuthenticatedPage extends StatelessComponent {
@override
Component build(BuildContext context) {
// Check for authentication cookie
final authToken = context.cookies['auth_token'];
if (authToken == null) {
// No auth token - redirect to login
context.setStatusCode(302);
context.setHeader('Location', '/login');
return div([], [text('Redirecting to login...')]);
}
// Validate token (simplified)
if (!isValidToken(authToken)) {
context.setStatusCode(401);
return div([], [
h1([], [text('Unauthorized')]),
p([], [text('Your session has expired.')]),
]);
}
// Get user info from headers
final userAgent = context.headers['user-agent'] ?? 'Unknown';
final acceptLanguage = context.headers['accept-language'] ?? 'en';
// Set custom response headers
context.setHeader('X-Frame-Options', 'DENY');
context.setHeader('X-Content-Type-Options', 'nosniff');
// Refresh the auth cookie
context.setCookie(
'auth_token',
authToken,
maxAge: 3600,
httpOnly: true,
secure: true,
sameSite: SameSite.strict,
);
return div([], [
h1([], [text('Welcome!')]),
p([], [text('Browser: $userAgent')]),
p([], [text('Language: $acceptLanguage')]),
]);
}
bool isValidToken(String token) {
// Token validation logic
return token.isNotEmpty;
}
}
Use Cases
Authentication & Authorization
final token = context.cookies['auth_token'];
if (token == null) {
context.setStatusCode(401);
return LoginPrompt();
}
Redirects
context.setStatusCode(302);
context.setHeader('Location', '/new-location');
Content Negotiation
final accept = context.headers['accept'];
if (accept?.contains('application/json') ?? false) {
context.setStatusCode(200, responseBody: jsonEncode(data));
context.setHeader('Content-Type', 'application/json');
}
Custom Caching
context.setHeader('Cache-Control', 'public, max-age=31536000');
context.setHeader('ETag', generateETag(content));
Session Management
context.setCookie(
'session_id',
generateSessionId(),
maxAge: 3600,
httpOnly: true,
sameSite: SameSite.strict,
);
These APIs only work on the server. If you try to use them in a client-rendered component (e.g., inside a @client component), they will throw an error.
See Also