Skip to content

docs(router): Document #[end_layout] and layout scoping behavior#628

Open
ThomasSteinbach wants to merge 1 commit intoDioxusLabs:mainfrom
ThomasSteinbach:docs-layout-scoping
Open

docs(router): Document #[end_layout] and layout scoping behavior#628
ThomasSteinbach wants to merge 1 commit intoDioxusLabs:mainfrom
ThomasSteinbach:docs-layout-scoping

Conversation

@ThomasSteinbach
Copy link

Problem

Fixes #627

The router documentation does not explain the stateful scoping behavior of #[layout()], nor does it mention the #[end_layout] attribute. This leads to a common bug where developers accidentally create nested/duplicate layouts.

Root Cause

The #[layout()] attribute creates a persistent, stateful scope that remains active for all subsequent routes until explicitly closed with #[end_layout].

When developers want multiple routes to share a layout, they naturally add #[layout()] to each route, which creates nested layouts instead of a shared layout:

// ❌ WRONG - Creates nested layouts
#[layout(Wrapper)]
#[route("/")]
Home {},

#[layout(Wrapper)]  // This NESTS inside the first layout!
#[route("/about")]
About {},

Result: The /about page renders with two Wrapper components (double header, double footer).

Solution

This PR adds comprehensive documentation explaining:

1. Stateful Layout Scoping

Documents that #[layout()] creates a persistent scope affecting all subsequent routes until closed.

2. The #[end_layout] Attribute

Explicitly documents #[end_layout] (analogous to #[end_nest] for nested routes).

3. Correct Pattern for Multiple Routes

Shows the proper way to apply one layout to multiple routes:

#[layout(Wrapper)]
    #[route("/")]
    Home {},
    
    #[route("/about")]
    About {},
#[end_layout]

4. Warning About Common Mistake

Includes a "Common Mistake" section with a working example showing the wrong pattern and explaining why it produces duplicate layouts.

5. Layout Scoping Rules

Clear bullet points explaining:

  • When layout scopes open
  • When they close
  • What happens with multiple #[layout()] attributes
  • Importance of indentation

6. Debugging Tips

Practical debugging guidance:

  • Checking HTML output with curl/DevTools
  • Using cargo expand to verify macro-generated nesting levels
  • Adding #[end_layout] to fix issues

Changes

  • docs-src/0.7/src/essentials/router/layouts.md: Added new section "Multiple routes sharing a layout" with subsections
  • packages/docs-router/src/doc_examples/outlet.rs: Added two new example modules:
    • multiple_routes: Shows correct pattern with #[end_layout]
    • wrong_pattern: Shows common mistake with nested layouts

Testing

Both new examples include tests that verify the rendered HTML:

  • multiple_routes: Renders single layout correctly
  • wrong_pattern: Demonstrates the duplicate layout bug (useful for understanding the issue)

Real-World Impact

This bit us in production. Our /tokens page rendered with 2 complete layouts while / rendered correctly. The fix was simple (#[end_layout]), but discovering it required inspecting generated HTML, using cargo expand, and reading Dioxus router source code.

Comparison with Existing Docs

The nested routes documentation already explains this pattern for #[nest()] and #[end_nest]. This PR brings layouts documentation to the same standard.

Alternative Approaches Considered

  1. Only document the correct pattern: Rejected - developers need to see the mistake to avoid it
  2. Remove #[end_layout] requirement: Not possible - this is core router behavior
  3. Add compile-time warning: Would require changes to router macro (out of scope for docs)

The documentation approach is appropriate and follows the pattern used for nested routes.

- Add section explaining stateful layout scoping
- Document #[end_layout] attribute to close layout scopes
- Add example showing correct pattern for multiple routes
- Add warning example showing common nested layout mistake
- Include debugging tips using cargo expand and HTML inspection
- Add layout scoping rules reference

Fixes DioxusLabs#627
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Document #[end_layout] attribute and layout scoping behavior

1 participant