Menu
CoddyTech

Redirects

Part of the Express Basics section of Coddy's Node.js journey. Lesson 10 of 20.

Pages move, and old links in bookmarks and search results should still lead somewhere.

app.get('/old-prices', (req, res) => {
    res.redirect(301, '/prices');
});

A redirect answers with a status and a Location header naming the new URL, and the browser asks for that URL at once. res.redirect sets both.

The status says how long the move lasts. 301 means moved for good: browsers and search engines remember the new address and stop asking for the old one. 302, the default when you pass no status, means for now, so they keep using the old URL.

challenge icon

Challenge

Easy
  • GET /menu has moved to /recipes for good.
  • GET /menu/:id has moved to /recipes/:id, same id.

Send GET /menu/3 and read the status and the Location header. Send GET /menu/42 too.

Try it yourself

import express from 'express';
import { recipes } from './data.js';

const app = express();

app.use(express.static('public'));

const escapeHtml = (text) =>
    text
        .replaceAll('&', '&')
        .replaceAll('<', '&lt;')
        .replaceAll('>', '&gt;')
        .replaceAll('"', '&quot;');

app.get('/', (req, res) => {
    const items = recipes.map((r) => `<li><a href="/recipes/${r.id}">${escapeHtml(r.title)}</a></li>`);
    res.send(`<link rel="stylesheet" href="/style.css"><h1>Recipe Box</h1><ul>${items.join('')}</ul>`);
});

// type('text') sends plain text, so each title shows on its own line.
app.get('/recipes', (req, res) => {
    const { tag } = req.query;
    const list = tag ? recipes.filter((recipe) => recipe.tags.includes(tag)) : recipes;
    res.type('text').send(list.map((recipe) => recipe.title).join('\n'));
});

app.get('/recipes/:id', (req, res) => {
    const recipe = recipes.find((r) => r.id === Number(req.params.id));
    if (!recipe) {
        res.status(404).send('No such recipe');
        return;
    }
    res.send(recipe.title);
});

app.get('/api/recipes', (req, res) => {
    res.json(recipes);
});

app.get('/api/recipes/:id', (req, res) => {
    const recipe = recipes.find((r) => r.id === Number(req.params.id));
    if (!recipe) {
        res.status(404).json({ error: 'No such recipe' });
        return;
    }
    res.json(recipe);
});

app.get('/about', (req, res) => {
    res.send('Recipe Box collects family recipes.');
});

app.listen(3000, () => {
    console.log('Recipe Box is running on port 3000');
});

All lessons in Express Basics