Dynamic Routes & Variables
A dynamic route is a route with a variable part in its URL, written in angle brackets like /user/<name> — 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 .
What You'll Learn in This Lesson
1 Capturing a Value From the URL
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.
2 Converters: Controlling the Type
By default a captured value is a string . A converter lets you require a specific type by writing it before the variable name, like <int:post_id> . 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.
- <string:x> — text without a slash (the default)
- <int:x> — a whole number, converted to int
- <float:x> — a decimal number, converted to float
- <path:x> — text that may include slashes
3 Multiple Variables in One Route
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.
🔬 Anatomy of a Dynamic Route
Pattern
What it captures
/user/<name>
Any text as a string, passed as name
/post/<int:id>
A whole number, passed as an int
/price/<float:amt>
A decimal, passed as a float
/files/<path:p>
Text that may contain slashes
🎯 Your Turn: Fill in the Blanks
Finish a route that greets a user by name and another that shows a numbered order. Replace each ___ .
Common Errors & Quick Reference
❌ 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. <int:post_id> only matches numbers, so a non-numeric value never reaches your function — that's working as intended.
Goal
Route pattern
Capture text
Capture an integer
Capture a decimal
Capture a path
🏆 Mini Challenge: A Blog URL Scheme
- A route /author/<name> that greets the author
- A route /article/<int:id> that shows an article number
- A route /article/<int:id>/comments/<int:c> for a specific comment
❓ Frequently Asked Questions
Lesson 3 complete — your routes are dynamic now!
You can capture values from URLs, convert them with <int:...> 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.
Continue this course
- Previous: Your First Route
- Next: HTTP Methods (GET & POST)