1
0

client_side_routing.py 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. """Handle dynamic routes in static exports via client-side routing.
  2. Works with /utils/client_side_routing.js to handle the redirect and state.
  3. When the user hits a 404 accessing a route, redirect them to the same page,
  4. setting a reactive state var "routeNotFound" to true if the redirect fails. The
  5. `wait_for_client_redirect` function will render the component only after
  6. routeNotFound becomes true.
  7. """
  8. from __future__ import annotations
  9. from reflex import constants
  10. from reflex.components.component import Component
  11. from reflex.components.core.cond import cond
  12. from reflex.vars.base import Var
  13. route_not_found: Var = Var(_js_expr=constants.ROUTE_NOT_FOUND)
  14. class ClientSideRouting(Component):
  15. """The client-side routing component."""
  16. library = "$/utils/client_side_routing"
  17. tag = "useClientSideRouting"
  18. def add_hooks(self) -> list[str | Var]:
  19. """Get the hooks to render.
  20. Returns:
  21. The useClientSideRouting hook.
  22. """
  23. return [f"const {constants.ROUTE_NOT_FOUND} = {self.tag}()"]
  24. def render(self) -> str:
  25. """Render the component.
  26. Returns:
  27. Empty string, because this component is only used for its hooks.
  28. """
  29. return ""
  30. def wait_for_client_redirect(component) -> Component:
  31. """Wait for a redirect to occur before rendering a component.
  32. This prevents the 404 page from flashing while the redirect is happening.
  33. Args:
  34. component: The component to render after the redirect.
  35. Returns:
  36. The conditionally rendered component.
  37. """
  38. return cond(
  39. condition=route_not_found,
  40. c1=component,
  41. c2=ClientSideRouting.create(),
  42. )
  43. class Default404Page(Component):
  44. """The NextJS default 404 page."""
  45. library = "next/error"
  46. tag = "Error"
  47. is_default = True
  48. status_code: Var[int] = Var.create(404)