Routing
Learn file-based routing, nested pages, dynamic params, typed params, regex routes, and reverse names.
This page focuses on the practical details. Use the quick links below to move to the previous, next, or related docs.
HyperDjango scans hyper/routes/ for +page.py files and turns folders into Django URL patterns.
The best way to learn routing is to start with static and dynamic routes first, then move to typed, regex, and catch-all patterns.
Basic Route Structure
Each route directory usually contains:
+page.pyindex.html
+page.py must define a class named PageView.
from __future__ import annotations
from django.http import HttpRequest
from hyperdjango.page import HyperView
class PageView(HyperView):
def get(self, request: HttpRequest) -> dict[str, str]:
return {"title": "About"}
Static Routes
Examples:
hyper/routes/index/+page.py->/hyper/routes/about/+page.py->/about/
Nested Routes
Routes nest by nesting folders.
hyper/routes/
dashboard/
index/
+page.py
settings/
+page.py
users/
[id]/
+page.py
This produces:
/dashboard//dashboard/settings//dashboard/users/<id>/
Dynamic Parameters
Use square brackets for dynamic params.
hyper/routes/blog/[slug]/+page.py:
from __future__ import annotations
from django.http import HttpRequest
from hyperdjango.page import HyperView
class PageView(HyperView):
def get(self, request: HttpRequest, slug: str) -> dict[str, str]:
return {"slug": slug}
Typed Parameters
Use Django path converters with the portable __ separator.
[int__id][slug__slug][path__path]
from __future__ import annotations
from django.http import HttpRequest
from hyperdjango.page import HyperView
class PageView(HyperView):
def get(self, request: HttpRequest, id: int) -> dict[str, int]:
return {"user_id": id}
Regex Parameters
If built-in converters are not enough, use inline regex syntax:
[name__regex]
Example:
hyper/routes/invites/[code__[A-Z0-9]{8}]/+page.py
from __future__ import annotations
from django.http import HttpRequest
from hyperdjango.page import HyperView
class PageView(HyperView):
def get(self, request: HttpRequest, code: str) -> dict[str, str]:
return {"code": code}
Composite Segments
One URL segment can contain multiple captured values and literals.
Examples:
[uidb36]-[key][kind]-v[version][uidb36__[0-9A-Za-z]+]-[key__.+]
from __future__ import annotations
from django.http import HttpRequest
from hyperdjango.page import HyperView
class PageView(HyperView):
def get(self, request: HttpRequest, uidb36: str, key: str) -> dict[str, str]:
return {"uidb36": uidb36, "key": key}
Catch-All Parameters
Use [...path] for catch-all paths.
hyper/routes/docs/[...path]/+page.py
from __future__ import annotations
from django.http import HttpRequest
from hyperdjango.page import HyperView
class PageView(HyperView):
def get(self, request: HttpRequest, path: str) -> dict[str, object]:
parts = [part for part in path.split("/") if part]
return {"raw_path": path, "parts": parts}
Route Groups
Use (group) to organize routes without affecting the public URL.
hyper/routes/(marketing)/pricing/+page.py
This compiles to /pricing/.
Reverse Names
HyperDjango generates Django URL names automatically.
hyper/routes/blog/[slug]/+page.py->hyper_blog_slughyper/routes/docs/[...path]/+page.py->hyper_docs_path_path
You can override it:
from __future__ import annotations
from hyperdjango.page import HyperView
class PageView(HyperView):
route_name = "blog_detail"
Prefixes and Slash Behavior
include_routes(url_prefix="app") mounts all compiled routes under /app/.
Compiled route generation also respects Django APPEND_SLASH behavior.
Conflict Detection
HyperDjango rejects ambiguous route shapes at compile time.
Use python manage.py hyper_routes in CI to catch conflicts early.