What if you could change your website's menu once and see it update everywhere instantly?
Why Routes and layouts in Deno? - Purpose & Use Cases
Imagine building a website where every page needs its own navigation menu, header, and footer. You have to copy and paste the same code into every page file manually.
This manual approach is slow and error-prone. If you want to change the menu, you must update every page separately. It's easy to forget one and cause inconsistent layouts.
Routes and layouts let you define common page structures once and reuse them automatically. Routes handle which page to show, and layouts wrap pages with shared parts like headers and footers.
function page() { return '<header>Menu</header><main>Content</main><footer>Footer</footer>'; }layout(() => '<header>Menu</header>' + routeContent() + '<footer>Footer</footer>');
This makes your website easier to build, update, and keep consistent across all pages.
Think of a blog where every post shares the same top menu and bottom contact info. Using routes and layouts, you update the menu once, and all posts reflect the change instantly.
Manual page setup causes repeated code and mistakes.
Routes decide which content to show based on the URL.
Layouts wrap pages with shared design elements automatically.
Practice
Solution
Step 1: Understand what routes do
Routes link a URL path to the content or page that should show when that URL is visited.Step 2: Compare options to this definition
Only To connect URLs to specific content or pages describes connecting URLs to content, which matches the purpose of routes.Final Answer:
To connect URLs to specific content or pages -> Option CQuick Check:
Routes = URL to content connection [OK]
- Confusing routes with styling or database tasks
- Thinking routes manage server hardware
- Mixing routes with layout responsibilities
Solution
Step 1: Recall Oak router syntax
In Oak, routes are defined using methods like router.get(path, handler).Step 2: Check each option's syntax
router.get('/home', (ctx) => { ctx.response.body = 'Home'; }); uses router.get with a context parameter and sets ctx.response.body, which is correct Oak syntax.Final Answer:
router.get('/home', (ctx) => { ctx.response.body = 'Home'; }); -> Option BQuick Check:
Oak route syntax = router.get(path, ctx) [OK]
- Using non-existent router methods like add or handle
- Not setting ctx.response.body for response
- Confusing callback parameters with Express.js style
const router = new Router();
router.get('/about', (ctx) => { ctx.response.body = 'About Page'; });
const layout = (content) => `Header ${content}`;
// Middleware to wrap response
app.use(async (ctx, next) => {
await next();
ctx.response.body = layout(ctx.response.body);
});
app.use(router.routes());
app.use(router.allowedMethods());Solution
Step 1: Understand route response
The route sets ctx.response.body to 'About Page' when '/about' is visited.Step 2: Understand middleware wrapping
The middleware runs after the route, wrapping the body with header and footer HTML using the layout function.Final Answer:
<header>Header</header>About Page<footer>Footer</footer> -> Option AQuick Check:
Middleware wraps route output with layout [OK]
- Ignoring middleware wrapping
- Assuming route output is unchanged
- Confusing order of middleware and routes
const router = new Router();
router.get('/contact', (ctx) => {
ctx.response.body = 'Contact Page';
});
const layout = (content) => `Header ${content}`;
app.use(router.routes());
app.use(router.allowedMethods());
app.use(async (ctx, next) => {
await next();
ctx.response.body = layout(ctx.response.body);
});Solution
Step 1: Analyze middleware order
router.routes() and router.allowedMethods() are registered before the layout middleware.Step 2: Recall route handler behavior in Oak
When router.routes() matches a route, it executes the handler. The handler sets the response body but does not call next(), terminating the middleware chain at that point.Step 3: Determine layout application
Subsequent middleware, including the layout wrapper, are never reached for matched routes. Thus, the layout is not applied.Final Answer:
Middleware wrapping layout runs after routes, so layout is not applied -> Option DQuick Check:
Middleware after router.routes() skipped on match [OK]
- Placing layout middleware after routes
- Forgetting to set ctx.response.body in route
- Misunderstanding middleware execution order
Solution
Step 1: Understand the requirement
The layout should wrap only routes under '/app', not all routes.Step 2: Evaluate each option
Use a middleware that checks if ctx.request.url.pathname starts with '/app' and wraps response body with layout only then uses middleware that checks the URL path and applies layout conditionally, which is correct and efficient.Step 3: Why other options fail
Apply the layout middleware globally to all routes without condition applies layout to all routes, ignoring the condition. Add the header and footer HTML directly inside each route handler under '/app' duplicates layout code in every route, which is not DRY. Use router.allowedMethods() to apply layout only to '/app' routes misuses router.allowedMethods(), which only handles HTTP method responses.Final Answer:
Use a middleware that checks if ctx.request.url.pathname starts with '/app' and wraps response body with layout only then -> Option AQuick Check:
Conditional middleware applies layout selectively [OK]
- Applying layout middleware globally without condition
- Repeating layout code in each route
- Misusing router.allowedMethods() for layout
Ready to prove it?
Pass the test and this pattern moves unknown
