Middleware
Middleware files (+middleware.js
) process requests before they reach your templates. Use middleware to:
- Check authentication
- Load shared data
- Set headers
- Validate requests
- Handle errors
Basic Example
/** @type {import('pocketpages').MiddlewareLoaderFunc} */
module.exports = function (api) {
const { request, redirect } = api
// Check auth
if (!request.header('Authorization')) {
redirect('/login')
return {}
}
// Load data
const categories = findRecordsByFilter('categories', {
filter: 'active = true',
})
return { categories }
}
How Middleware Works
Middleware executes hierarchically from root to leaf:
pb_hooks/pages/
+middleware.js # Runs first (all routes)
products/
+middleware.js # Runs second (/products/*)
[id]/
+middleware.js # Runs third (/products/[id]/*)
For URL /products/123
:
/+middleware.js
runs/products/+middleware.js
runs/products/[id]/+middleware.js
runs
Common Use Cases
Auth Guard
/** @type {import('pocketpages').MiddlewareLoaderFunc} */
module.exports = function (api) {
const { request, redirect } = api
const session = request.cookie('session')
if (!session) {
redirect('/login')
return {}
}
const user = findRecordByFilter('users', {
filter: `session = "${session}"`,
})
return { user }
}
Request Validation
/** @type {import('pocketpages').MiddlewareLoaderFunc} */
module.exports = function (api) {
const { request, response, params } = api
if (!params.id?.match(/^[0-9]+$/)) {
response.status(400)
return { error: 'Invalid ID' }
}
return {}
}
Loading Data
/** @type {import('pocketpages').MiddlewareLoaderFunc} */
module.exports = function (api) {
const { params, response } = api
const product = findRecordByFilter('products', {
filter: `id = "${params.id}"`,
})
if (!product) {
response.status(404)
return { error: 'Not found' }
}
return { product }
}
Using Middleware Data
Access middleware data in templates through data
:
<% if (data.user) { %>
<h1>Welcome, <%= data.user.name %></h1>
<% if (data.product) { %>
<h2><%= data.product.name %></h2>
<p><%= data.product.description %></p>
<% } %>
<% } %>
Important Notes
- Middleware runs before page loaders (
+load.js
) - All middleware along the route path executes
- Return an object to pass data to templates
- Return early to stop processing
- Keep processing efficient
HTTP Method-Specific Middleware
In addition to +middleware.js
which runs for all HTTP methods, you can create method-specific middleware files that only run for specific HTTP methods:
// +get.js - Only runs for GET requests
/** @type {import('pocketpages').MiddlewareLoaderFunc} */
module.exports = function (api) {
// Handle GET requests
return {}
}
// +post.js - Only runs for POST requests
/** @type {import('pocketpages').MiddlewareLoaderFunc} */
module.exports = function (api) {
// Handle POST requests
return {}
}
Supported method-specific middleware files:
+get.js
+post.js
+put.js
+patch.js
+delete.js
These files follow the same hierarchical execution order as +middleware.js
.