Dynamic Routes & Variables
A dynamic route is a route with a variable part in its URL, written in angle brackets like — the value in that spot is captured from the URL and passed straight into your view function.
Learn Dynamic Routes & Variables in our free Flask course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…
Part of the free Flask course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
In this lesson you'll capture values from URLs, use converters to control their type, and build flexible pages that respond to many addresses with a single function. Run any example locally with flask run .
A dynamic route has a piece of its path wrapped in angle brackets . The text inside the brackets is a variable name . When a request matches, Flask pulls that part of the URL out and passes it to your view function as an argument with the same name.
In the example below, visiting /user/Ada calls profile(username="Ada") . The same single function handles /user/Grace , /user/Linus , and any other name.
By default a captured value is a string . A converter lets you require a specific type by writing it before the variable name, like . Flask both checks the value matches and converts it for you — so post_id arrives as a real Python int .
If the URL doesn't match the converter (for example /post/hello when an int is expected), Flask returns a 404 instead of calling your function.
A route can capture more than one value. Each angle-bracket section becomes one argument, in order. The route below captures a category as text and an item id as an integer.
The order matters: the first bracket maps to the first parameter, the second bracket to the second. The names just need to match between the route and the function signature.
Finish a route that greets a user by name and another that shows a numbered order. Replace each ___ .
❌ TypeError: profile() missing 1 required positional argument
Your view function takes a parameter but you forgot the matching variable in the route, or the names don't match. The bracket name and the parameter name must be identical.
The converter rejected the value. only matches numbers, so a non-numeric value never reaches your function — that's working as intended.
Lesson 3 complete — your routes are dynamic now!
You can capture values from URLs, convert them with and friends, and handle several variables in one route. One function can now serve thousands of URLs.
🚀 Up next: HTTP Methods (GET & POST) — handle form submissions and learn the difference between reading and sending data.
Practice quiz
How do you mark a variable part of a URL in a Flask route?
- with curly braces {name}
- with angle brackets <name>
- with a colon :name
- with parentheses (name)
Answer: with angle brackets <name>. Angle brackets like /user/<name> capture that part of the URL.
In @app.route('/user/<username>'), how is the value passed to the view?
- as a function argument named username
- via request.args
- in a global variable
- username
Answer: as a function argument named username. The captured segment is passed as the matching function parameter.
What type does a captured value have by default (no converter)?
- int
- bytes
- string
- list
Answer: string. Without a converter, captured URL values are strings.
Which converter requires a whole number and passes it as an int?
- <num:id>
- <digit:id>
- <integer:id>
- <int:id>
Answer: <int:id>. <int:id> matches whole numbers and converts the value to a Python int.
What happens when /post/abc hits a route declared as /post/<int:id>?
- Flask returns a 404 Not Found
- id becomes the string 'abc'
- Flask raises a 500 error
- id becomes 0
Answer: Flask returns a 404 Not Found. A non-integer does not match the converter, so the route is not selected and Flask returns 404.
Which converter matches text that may contain slashes?
- <slash:p>
- <path:p>
- <any:p>
- <url:p>
Answer: <path:p>. <path:p> accepts segments that include forward slashes.
Which converter is used for a decimal number?
- <decimal:x>
- <double:x>
- <float:x>
- <number:x>
Answer: <float:x>. <float:x> matches a decimal and passes it as a Python float.
Can a single route capture more than one variable?
- Yes — each angle-bracket section is one argument
- No, only one is allowed
- Only with query strings
- Only if both are ints
Answer: Yes — each angle-bracket section is one argument. A route like /<category>/<int:item_id> maps each bracket to a parameter in order.
For /shop/<category>/<int:item_id>, how does the view receive them?
- both as strings
- as request.args
- as two parameters: category (str) and item_id (int)
- as a single dict
Answer: as two parameters: category (str) and item_id (int). Each bracket becomes a parameter; the int converter makes item_id an int.
What must match between the route bracket and the view function?
- the file name
- the HTTP method
- the return type
- the variable/parameter name
Answer: the variable/parameter name. <username> in the route must pair with a username parameter in the function.