Protected routes keep parts of your website safe by only letting certain people see them. Middleware helps check who is allowed before showing the page.
When you want only logged-in users to see their profile page.
When you need to stop visitors from accessing admin pages.
When you want to check user permissions before loading a page.
When you want to redirect users to login if they are not signed in.
Syntax
Astro
export async function middleware(context) {
// Check user session or token
if (!context.locals.user) {
return new Response(null, { status: 302, headers: { Location: '/login' } });
}
return context.next();
}
Middleware runs before your page loads to check conditions.
Use context.locals to access user info stored during requests.
Examples
This middleware redirects users to the login page if they are not logged in.
Astro
export async function middleware(context) {
if (!context.locals.user) {
return new Response(null, { status: 302, headers: { Location: '/login' } });
}
return context.next();
}
This middleware blocks access if the user is not an admin.
Astro
export async function middleware(context) {
if (context.locals.user?.role !== 'admin') {
return new Response('Access denied', { status: 403 });
}
return context.next();
}
Sample Program
This example middleware checks if a user is logged in. If not, it sends them to the login page. If yes, it shows a welcome message with their name.
Astro
export async function middleware(context) {
// Simple check for logged-in user
if (!context.locals.user) {
// Redirect to login page
return new Response(null, { status: 302, headers: { Location: '/login' } });
}
// Allow access
return context.next();
}
// Example page component
---
const user = Astro.locals.user;
---
<html lang="en">
<head>
<title>Protected Page</title>
</head>
<body>
<h1>Welcome, {user.name}!</h1>
<p>This page is protected and only visible to logged-in users.</p>
</body>
</html>
OutputSuccess
Important Notes
Middleware runs on the server before the page loads.
Always test your redirects to avoid loops.
Store user info safely in context.locals during authentication.
Summary
Protected routes keep pages safe for certain users only.
Middleware checks user status before showing pages.
Redirect users to login if they are not allowed access.
Practice
(1/5)
1. What is the main purpose of middleware in Astro when protecting routes?
easy
A. To check user access before loading a page
B. To style the page content dynamically
C. To fetch data after the page loads
D. To optimize images on the page
Solution
Step 1: Understand middleware role
Middleware runs before a page loads to perform checks or actions.
Step 2: Identify middleware use in protected routes
It checks if a user has permission to access certain pages before showing them.
Final Answer:
To check user access before loading a page -> Option A
Quick Check:
Middleware checks access = D [OK]
Hint: Middleware runs first to check access before page loads [OK]
Common Mistakes:
Thinking middleware styles pages
Assuming middleware fetches data after load
Confusing middleware with image optimization
2. Which syntax correctly defines a middleware matcher for protecting all routes under /dashboard in Astro?
easy
A. export const matcher = '/dashboard/*';
B. export const matcher = ['/dashboard/*'];
C. export const matcher = ['/dashboard'];
D. export const matcher = '/dashboard';
Solution
Step 1: Recall matcher syntax
Matcher must be an array of strings specifying route patterns.
Step 2: Match all routes under /dashboard
Using '/dashboard/*' inside an array matches all subpaths.
Final Answer:
export const matcher = ['/dashboard/*']; -> Option B
Quick Check:
Matcher is array with pattern string = A [OK]
Hint: Matcher must be an array of route strings [OK]
Common Mistakes:
Using string instead of array for matcher
Missing wildcard * to match subroutes
Using exact path without wildcard for nested routes
3. Given this middleware code in Astro, what happens when a user visits /profile without a valid token?
The middleware checks if the 'authorization' header exists in the request.
Step 2: Redirect if no token
If token is missing, middleware redirects user to '/login'.
Final Answer:
User is redirected to /login -> Option C
Quick Check:
No token means redirect to /login = A [OK]
Hint: No token triggers redirect to login [OK]
Common Mistakes:
Assuming user sees page without token
Expecting error instead of redirect
Redirecting to wrong path
4. Identify the error in this Astro middleware code meant to protect /admin routes:
export const matcher = '/admin/*';
export function middleware({ request, redirect }) {
const user = request.headers.get('user');
if (user !== 'admin') {
redirect('/not-authorized');
}
}
medium
A. request.headers.get does not exist
B. redirect should be called with await
C. middleware must be async function
D. matcher should be an array, not a string
Solution
Step 1: Check matcher syntax
Matcher must be an array of strings, not a single string.
Step 2: Confirm redirect usage
Redirect can be called synchronously; no await needed here.
Final Answer:
matcher should be an array, not a string -> Option D
Quick Check:
Matcher array required = C [OK]
Hint: Matcher must always be an array even for one route [OK]
Common Mistakes:
Using string instead of array for matcher
Thinking redirect needs await
Confusing request.headers API
5. You want to protect both /dashboard and /settings routes using middleware in Astro. Which matcher setup correctly protects both paths and their subpaths?
hard
A. export const matcher = ['/dashboard/*', '/settings/*'];
B. export const matcher = ['/dashboard', '/settings'];
C. export const matcher = ['/dashboard*', '/settings*'];
D. export const matcher = ['/dashboard/**', '/settings/**'];
Solution
Step 1: Understand wildcard usage
'/*' matches all subpaths under a route, ensuring protection of nested pages.
Step 2: Verify matcher array format
Matcher must be an array of strings with correct wildcard patterns.
Final Answer:
export const matcher = ['/dashboard/*', '/settings/*']; -> Option A
Quick Check:
Array with '/*' wildcard protects subpaths = B [OK]
Hint: Use '/*' wildcard in array to protect all subroutes [OK]
Common Mistakes:
Omitting wildcard to protect subpaths
Using incorrect wildcard like '**'
Using string instead of array for matcher
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.