Skip to content

Conversation

@nielsenko
Copy link
Collaborator

@nielsenko nielsenko commented Nov 20, 2025

Update WebServer Documentation

Summary

Updates the WebServer documentation to match the Serverpod 3.0 implementation and adds coverage of routing, middleware, typed headers, and static file handling.

Changes

Fixes

  • Corrected Component* references to actual Widget* classes (rolled-back rename was never fixed in docs)
  • Updated upgrade guide to reflect actual API changes
  • Made StaticRoute cache control methods static (implementation bug fix)

New Sections

Routing

  • Custom Route classes with handleCall()
  • HTTP method handling
  • Path parameters (symbol-based: pathParameters[#id])
  • Wildcards: /* and /** (tail-match only, O(h) performance)
  • Fallback routes
  • Modular routes using injectIn() override

Middleware

  • Creating and applying middleware
  • Error handling middleware
  • API key validation
  • CORS configuration
  • ContextProperty for request-scoped data

Typed Headers

  • Reading and setting typed headers
  • AuthorizationHeader (Bearer, Basic, Digest)
  • CacheControlHeader
  • ContentDispositionHeader
  • CookieHeader/SetCookieHeader
  • Creating custom typed headers with HeaderAccessor

Static Files

  • CacheBustingConfig for content-based versioning
  • ETag and Last-Modified support
  • Cache control integration

Summary by CodeRabbit

  • Documentation

    • Updated web-server docs to use widget-centric terminology and examples.
    • Migration guide expanded with revised naming guidance, static file routing examples, and enhanced caching configuration.
  • Refactor

    • Public-facing API names and examples reorganized for consistent widget/template semantics.
    • Code samples and patterns updated to reflect the new route/build rendering flow.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Nov 20, 2025

Important

Review skipped

Auto reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Documentation updated to reflect a widget-centric web-server API: types and examples renamed (ComponentRoute → WidgetRoute, Component → WebWidget/TemplateWidget), build signatures changed to return TemplateWidget, and upgrade guidance revised for static routes and caching factories.

Changes

Cohort / File(s) Change Summary
Web server concepts doc
docs/06-concepts/18-webserver.md
Replaced Component-based terminology with widget-centric names; ComponentRouteWidgetRoute; ComponentWebWidget/TemplateWidget; build signatures now accept (Session, Request) and return TemplateWidget; updated headings and code examples to use Widget/TemplateWidget patterns and template path conventions.
Upgrade guide (v3) doc
docs/08-upgrading/06-upgrade-to-three.md
Renamed section to reflect web server changes; adjusted migration guidance to prefer TemplateWidget/WebWidget; updated examples for special types (Json/Redirect/List components) and route registration; documented StaticRoute factory methods (directory, publicImmutable, public, privateNoCache, noStore) and cache-control examples.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

  • Verify consistent renames across both docs: WidgetRoute, TemplateWidget, WebWidget
  • Check code samples compile with the new signatures and return types (build: (Session, Request) -> TemplateWidget)
  • Ensure upgrade guide mappings (old → new names) are accurate and that StaticRoute factory examples are correct and coherent with the concepts doc

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main change: updating WebServer documentation for Serverpod 3.0. It directly matches the core objective of correcting outdated references and adding comprehensive new documentation sections.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nielsenko
Copy link
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Nov 20, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
docs/06-concepts/18-webserver.md (1)

3-8: Address static analysis hints for stronger, more accurate language.

Three style/grammar issues should be corrected:

  1. Line 5: "very easy" uses a weak intensifier. Consider replacing with a stronger verb or more specific description.
  2. Line 8: "3rd party" should be hyphenated as "third-party" for proper compound adjective formatting.
  3. Line 167: "gives you access to" uses a weak verb. Consider "provides" or a more specific term.

These are minor polish issues but will improve documentation quality per static analysis feedback.

Apply this diff to fix these issues:

-In addition to the application server, Serverpod comes with a built-in web
-server. The web server allows you to access your database and business layer the
-same way you would from a method call from an app. This makes it very easy to
-share data for applications that need both an app and traditional web pages. You
-can also use the web server to create webhooks or generate custom REST APIs to
-communicate with 3rd party services.
+In addition to the application server, Serverpod comes with a built-in web
+server. The web server allows you to access your database and business layer the
+same way you would from a method call from an app. This makes it simple to
+share data for applications that need both an app and traditional web pages. You
+can also use the web server to create webhooks or generate custom REST APIs to
+communicate with third-party services.

And for line 167, update it from "gives you access to" to "provides" when you encounter it in context.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 774dd92 and bdd5cf6.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (2)
  • docs/06-concepts/18-webserver.md (1 hunks)
  • docs/08-upgrading/06-upgrade-to-three.md (1 hunks)
🧰 Additional context used
🪛 LanguageTool
docs/06-concepts/18-webserver.md

[style] ~5-~5: As an alternative to the over-used intensifier ‘very’, consider replacing this phrase.
Context: ... method call from an app. This makes it very easy to share data for applications that nee...

(EN_WEAK_ADJECTIVE)


[grammar] ~8-~8: Use a hyphen to join words.
Context: ...custom REST APIs to communicate with 3rd party services. :::caution Serverpod's...

(QB_NEW_EN_HYPHEN)


[style] ~167-~167: Try using a synonym here to strengthen your writing.
Context: ...idgetRouteclass'build` method. This gives you access to all the features you typicall...

(GIVE_PROVIDE)

🔇 Additional comments (7)
docs/06-concepts/18-webserver.md (5)

25-67: Well-structured introduction to basic routing with clear examples.

The section correctly introduces WidgetRoute and TemplateWidget terminology. Code examples at lines 44–46 and 57–58 are clear and idiomatic. Explanation of template values and the values field is helpful for developers new to this pattern.


69-162: Excellent coverage of static file handling and cache-busting strategy.

The section provides clear motivation and comprehensive examples for the CacheBustingConfig feature. The explanation of content-based hashing, custom separators, and transparent URL rewriting is well-structured and should help developers implement effective caching strategies. The conditional request support (ETags, Last-Modified) documentation adds important context for cache validation.

One minor readability note: the StaticRoute.directory() example (lines 102–104) is quite dense with nested method calls. Consider breaking it across more lines for improved readability in the actual documentation (if not already formatted that way in the source).


171-467: Comprehensive advanced routing section with clear patterns and practical examples.

This section effectively covers:

  • Custom route handlers via the Route base class and handleCall() override
  • HTTP method routing with switch expressions
  • Path parameters using symbol syntax (request.pathParameters[#paramName])—correctly implemented and consistent
  • Wildcard routing with clear distinction between /* (single-level) and /** (tail-match with O(h) performance guarantee, as per PR objectives)
  • Modular route composition via injectIn() with realistic CRUD and nested module examples

The note about ContextProperty at lines 330–339 correctly distinguishes between Route.handleCall() (which receives Session and Request) and modular handlers (which only receive Request, accessed via request.session). This detail prevents a common confusion point.


469-789: Excellent middleware documentation with clear patterns and thorough ContextProperty coverage.

The middleware section provides:

  • Clear examples of basic, logging, authentication, CORS, and error-handling middleware
  • Explicit documentation of middleware execution order with visual explanation (lines 586–593)
  • A particularly strong subsection on ContextProperty (lines 595–778) that thoroughly addresses a potentially confusing pattern

The ContextProperty documentation is exemplary—it explains the why (Request immutability), provides multiple realistic examples (request ID tracking, tenant identification, feature flags, rate limiting), includes safe access patterns (getOrNull()), and lists best practices. The multi-tenant example (lines 695–735) is production-grade and instructive.

The distinction between middleware execution and the Session parameter availability (lines 609–612) prevents a common misunderstanding about scoped context.


791-1101: Comprehensive typed headers documentation with exemplary custom header creation guide.

The typed headers section provides:

  • Clear motivation for typed headers over manual string parsing
  • Accessible examples of common request/response headers
  • Detailed subsections for each major header type (Authorization, CacheControl, ContentDisposition, Cookie)
  • Production-grade complete examples (secure API, file download, session management)

The custom typed headers section (lines 986–1101) is particularly strong:

  • Clear 3-step process (class definition with parsing logic, HeaderCodec, HeaderAccessor)
  • Realistic ApiVersionHeader example with proper validation
  • Multi-value header pattern with CustomTagsHeader
  • Extension methods pattern for ergonomic property-style access
  • Concise best-practices summary (lines 1103–1110)

This enables developers to confidently extend the system for application-specific headers. The pattern documentation is clear enough for a developer to apply it to their own headers without confusion.

docs/08-upgrading/06-upgrade-to-three.md (2)

3-33: Clear widget class naming migration guidance with helpful before/after example.

The widget naming section correctly explains:

  • WidgetTemplateWidget rename
  • AbstractWidgetWebWidget rename
  • Legacy names remain available for backward compatibility
  • WidgetRoute class remains unchanged

The before/after code example (lines 19–32) clearly demonstrates the migration pattern. Marking the old class with a deprecation comment would be a minor enhancement but is not required—the surrounding text makes it clear this is deprecated.


35-93: Effective static route migration guide with clear before/after examples.

The static route section correctly documents:

  • Migration from RouteStaticDirectory to StaticRoute.directory()
  • Available cache control factory methods (lines 74–77)
  • Both built-in and custom cache control factory patterns

The before/after code examples (lines 42–57) clearly show the API transition. The custom factory function example (lines 81–92) demonstrates that developers have flexibility beyond the built-in factories.

Minor observation: The factory method descriptions at lines 74–77 (e.g., StaticRoute.public(maxAge: seconds)) could be slightly more explicit about whether maxAge is required or optional. However, this level of detail is appropriate for an upgrade guide; developers can check the API documentation or IDE hints for parameter signatures. The examples provided are sufficient for migration purposes.

@nielsenko nielsenko self-assigned this Nov 20, 2025
@nielsenko nielsenko requested a review from Copilot November 20, 2025 11:28
@nielsenko nielsenko marked this pull request as ready for review November 20, 2025 11:32
@nielsenko nielsenko requested a review from a team November 20, 2025 11:32
Copilot finished reviewing on behalf of nielsenko November 20, 2025 11:32
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR updates the Serverpod web server documentation to reflect the Serverpod 3.0 implementation, correcting outdated class references and adding comprehensive coverage of routing, middleware, typed headers, and static file handling.

Key changes:

  • Corrects Component* class references to actual Widget* classes (fixes rolled-back rename that was never updated in docs)
  • Updates upgrade guide with correct API changes and new StaticRoute patterns
  • Adds extensive documentation for routing (custom routes, HTTP methods, path parameters, wildcards, modular routes)
  • Documents middleware system (creation, error handling, CORS, API validation, ContextProperty)
  • Documents typed headers system (AuthorizationHeader, CacheControlHeader, cookies, custom headers)
  • Documents static file handling (cache-busting, ETags, Last-Modified)

Reviewed Changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 8 comments.

File Description
docs/08-upgrading/06-upgrade-to-three.md Updates upgrade guide to reflect actual Serverpod 3.0 widget class naming and StaticRoute API changes
docs/06-concepts/18-webserver.md Comprehensive expansion covering routing, middleware, typed headers, and static file handling

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@nielsenko
Copy link
Collaborator Author

@copilot All the broken formatting of code-snippets should be reverted now. Please check, and close resolved comments.

Copy link
Contributor

Copilot AI commented Nov 20, 2025

@nielsenko I've opened a new pull request, #343, to work on those changes. Once the pull request is ready, I'll request review from you.

@nielsenko
Copy link
Collaborator Author

@copilot I fixed the formatting. Just verify and close your comments

Copy link
Contributor

Copilot AI commented Nov 20, 2025

@nielsenko I've opened a new pull request, #344, to work on those changes. Once the pull request is ready, I'll request review from you.

@nielsenko
Copy link
Collaborator Author

Fuck off @copilot 😡

Copy link
Contributor

Copilot AI commented Nov 20, 2025

@nielsenko I've opened a new pull request, #345, to work on those changes. Once the pull request is ready, I'll request review from you.

@nielsenko
Copy link
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Nov 20, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
docs/06-concepts/18-webserver.md (2)

195-210: HTTP request/response examples should use dedicated HTTP code blocks.

The HTTP examples at lines 195-210 are currently embedded as Dart comments within a code fence. Consider moving these to a separate HTTP code block for clarity:

# Client first request
GET /static/logo.png HTTP/1.1
Host: example.com

HTTP/1.1 200 OK
ETag: "abc123"
Last-Modified: Tue, 15 Nov 2024 12:00:00 GMT
Content-Length: 12345

[file content]

# Client subsequent request
GET /static/logo.png HTTP/1.1
Host: example.com
If-None-Match: "abc123"

HTTP/1.1 304 Not Modified
ETag: "abc123"

[no body - saves bandwidth]

This improves readability and makes the examples scannable.


10-14: Optional: Consider style improvement for "giving you access."

Static analysis suggests replacing "giving you access" with a synonym like "providing" for variety. While not critical, this could strengthen the writing:

- Serverpod's web server is built on the [Relic](https://github.com/serverpod/relic) framework, giving you access to its routing engine, middleware system, and typed headers.
+ Serverpod's web server is built on the [Relic](https://github.com/serverpod/relic) framework, providing access to its routing engine, middleware system, and typed headers.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bdd5cf6 and 68bd650.

📒 Files selected for processing (1)
  • docs/06-concepts/18-webserver.md (3 hunks)
🧰 Additional context used
🪛 LanguageTool
docs/06-concepts/18-webserver.md

[style] ~11-~11: Try using a synonym here to strengthen your writing.
Context: .../github.com/serverpod/relic) framework, giving you access to its routing engine, middlewar...

(GIVE_PROVIDE)


[style] ~219-~219: Try using a synonym here to strengthen your writing.
Context: ...idgetRouteclass'build` method. This gives you access to all the features you typicall...

(GIVE_PROVIDE)


[grammar] ~800-~800: Use a hyphen to join words.
Context: ...y-catch blocks to every route, use error handling middleware to catch exceptions ...

(QB_NEW_EN_HYPHEN)


[grammar] ~803-~803: Use a hyphen to join words.
Context: ... consistent error responses. #### Error handling middleware Error handling midd...

(QB_NEW_EN_HYPHEN)


[grammar] ~805-~805: Use a hyphen to join words.
Context: .... #### Error handling middleware Error handling middleware wraps all your route...

(QB_NEW_EN_HYPHEN)


[grammar] ~841-~841: Use a hyphen to join words.
Context: ...andlingMiddleware, '/'); ``` With error handling middleware in place, your route...

(QB_NEW_EN_HYPHEN)


[grammar] ~850-~850: Use a hyphen to join words.
Context: ...ver Error response. However, using error handling middleware gives you control ov...

(QB_NEW_EN_HYPHEN)

🔇 Additional comments (5)
docs/06-concepts/18-webserver.md (5)

24-30: Clear terminology introduction—terminology shift well-established.

The section correctly introduces WidgetRoute and TemplateWidget as primary concepts, aligning with the Serverpod 3.0 widget-centric model mentioned in the PR objectives.


49-78: Widget terminology correctly applied throughout examples.

The WidgetRoute and TemplateWidget usage is consistent and correct. The super(name: 'my_page') pattern for template identification is clearly demonstrated.


317-376: Path parameters and modular routes comprehensively documented.

The use of symbols for path parameter access (request.pathParameters[#id]) is clearly demonstrated and consistently applied across multiple examples (lines 335, 372-375, 494, 543, 582, 1431). The modular route pattern with injectIn() is well-explained with clear examples.


875-1141: ContextProperty patterns are comprehensive and well-documented.

The section clearly demonstrates context property definition, middleware usage for setting values, and route usage for reading values. The multi-tenant example and safe access patterns (getOrNull()) are helpful real-world scenarios.


1155-1681: Typed headers comprehensively documented with practical examples.

The section covers reading, setting, and creating custom typed headers. Authentication schemes (Bearer, Basic, Digest), cache directives, and cookie security patterns (SameSite, HttpOnly, Secure) are all clearly explained with working examples. The custom header creation section with HeaderCodec and HeaderAccessor is well-structured.

The documentation incorrectly referenced ComponentRoute and Component classes
that don't exist. The Widget to Component rename was rolled back in the
implementation but the docs were never updated.

Changes:
- Reverted ComponentRoute → WidgetRoute
- Reverted Component → TemplateWidget/WebWidget
- Reverted ListComponent, JsonComponent, RedirectComponent → ListWidget, JsonWidget, RedirectWidget
- Updated RouteStaticDirectory → StaticRoute.directory()
- Fixed method signature: HttpRequest request → Request request
- Rewrote upgrade guide to reflect actual changes (Widget → TemplateWidget deprecation)
- Added StaticRoute cache control examples using the newly static methods
Added detailed documentation for WebServer's advanced routing and middleware
features, including:

Routing:
- Custom Route classes for REST APIs and custom response handling
- HTTP method handling (GET, POST, PUT, DELETE, PATCH, etc.)
- Path parameters and wildcard matching (*, **)
- Fallback routes for 404 handling
- Request object usage and query parameters

Middleware:
- Creating custom middleware functions
- Authentication middleware patterns
- CORS middleware implementation
- Middleware execution order and path hierarchy
- ContextProperty for request-scoped data
- Built-in logRequests() middleware

All examples are based on the Relic framework that WebServer is built on,
with Serverpod-specific integration points highlighted.
Added comprehensive documentation for creating modular routes by overriding
the injectIn method, including:

- Detailed path parameters section with :paramName syntax
- How to extract and validate path parameters using symbols (pathParameters[#id])
- Multiple path parameters in a single route
- Complete CRUD module example using proper RESTful path parameters
- Path parameter validation and error handling
- Wildcards section (single-level * and multi-level **)
- Pattern for composing multiple sub-modules into a parent module
- Best practices for organizing complex APIs

The injectIn override pattern enables:
- Hierarchical route organization
- Reusable route modules
- Complex API composition from smaller focused modules
- Separation of route registration from handler implementation

Examples show practical RESTful API patterns:
- GET /api/users - List all
- GET /api/users/:id - Get by ID (access via pathParameters[#id])
- POST /api/users - Create
- PUT /api/users/:id - Update by ID
- DELETE /api/users/:id - Delete by ID

All examples include proper path parameter extraction using symbols,
validation, and error handling with appropriate HTTP status codes.
Expanded the ContextProperty section with detailed documentation on using
context properties for request-scoped data:

Overview:
- Why use ContextProperty instead of modifying Request
- Common use cases (auth, rate limiting, request IDs, multi-tenant, feature flags)

Creating and Using:
- How to define ContextProperty instances
- Setting values in middleware
- Accessing values in routes
- Safe access with getOrNull()
- Using default values

Complete Examples:
- Full authentication middleware with bearer token validation
- Role-based authorization middleware (requireRole)
- Multi-tenant application with multiple context properties
- Request ID tracking and logging
- Combining multiple properties in routes

Best Practices:
- Define as top-level constants or static fields
- Use descriptive naming conventions
- Set in middleware, read in routes
- Use getOrNull() for optional values
- Leverage type safety

This pattern is essential for building production-ready web applications
with proper separation of concerns between authentication, authorization,
and business logic.
… cases

- Added note that Session already provides auth info
- Changed examples to focus on request ID tracking, tenant identification, and API versioning
- Removed redundant authentication middleware examples
- Better demonstrates web-specific use cases for ContextProperty
- Changed from user authentication to API key validation
- Added info box clarifying to use Serverpod's built-in auth for users
- Keeps middleware examples focused on web-specific validations
- Add info box explaining error handling is omitted for brevity
- Document automatic 500/400 error responses for uncaught exceptions
- Clarify Session access pattern difference between Route.handleCall() and modular routes
- Explain that injectIn handlers use request.session while handleCall receives Session parameter
- Add comprehensive error handling middleware example
- Handles FormatException for invalid JSON
- Logs errors with stack traces
- Returns appropriate HTTP status codes (400/500)
- Update earlier error handling info box to recommend middleware approach
- Emphasizes centralized error handling over per-route try-catch blocks
- Add context for special widgets and static files
- Introduce Advanced routing section with overview of patterns covered
- Explain the value of custom Route classes vs WidgetRoute
- Add prose explaining modular routes and when to use them
- Introduce middleware concept with explanation of cross-cutting concerns
- Add context for ContextProperty and why immutability requires it
- Explain typed headers benefits vs string-based parsing
- Introduce custom typed headers with step-by-step overview

These additions help readers understand not just *how* to use features, but *why* they exist and *when* to use them.
- Add Relic framework context in introduction with link
- Clarify Session vs ContextProperty distinction
  - Emphasize request ID as purely request-scoped (not session data)
  - Reorder use cases to prioritize request ID tracking
  - Add note about when tenant should/shouldn't be in session
- Elevate error handling from info box to dedicated subsection
  - Change from h3 to h2 section under Middleware
  - Add comprehensive explanation of exception handling
  - List common exceptions and their HTTP status codes
  - Explain fallback behavior when exceptions escape middleware
- Simplify error handling info box to reference main section
- Replace weak intensifier 'very easy' with 'simple'
- Hyphenate 'third-party' as compound adjective
- Keep 'gives you access to' for clarity over 'provides'
Restored from commit before rewrap (aefd54c) and reapplied content changes:
- Relic framework context with link
- Style improvements (simple, third-party)
- Error handling elevation and clarification
- Session vs ContextProperty distinction improvements

Code blocks now properly formatted with correct indentation.
Replace Dart comment pseudo-code with actual HTTP request/response format using http language tag. Separates initial and subsequent requests for clarity.
Comment on lines 18 to 20
Serverpod's web server is still experimental, and the APIs may change in the
future. This documentation should give you some hints on getting started, but we
plan to add more extensive documentation as the web server matures.
Copy link
Collaborator Author

@nielsenko nielsenko Nov 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we drop this now? Or wait until Relic 1.0? Or even further?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should drop it. With Serverpod 3 the web server is no longer experimental :D

Comment on lines 82 to 85
In the future, we plan to add a widget library to Serverpod with widgets
corresponding to the standard widgets used by Flutter, such as Column, Row,
Padding, Container, etc. This would make it possible to render server-side
widgets with similar code used within Flutter.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still, or are we aiming for good Jaspr support?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove this not to have promises in the docs. I think Jaspr is probably good enough.

Comment on lines 439 to 467
### Modular routes with injectIn

As your web server grows, managing dozens of individual route registrations can
become unwieldy. Modular routes solve this by letting you group related
endpoints into reusable modules. For example, you might create a
`UserCrudModule` that handles all user-related endpoints (`GET /users`,
`POST /users`, `PUT /users/:id`, etc.) in a single cohesive unit.

The key to modular routes is the `injectIn()` method. When you call
`pod.webServer.addRoute(route, path)`, Serverpod calls `route.injectIn(router)`
on a router group for that path. By overriding `injectIn()`, you can register
multiple handler functions instead of implementing a single `handleCall()`
method. This pattern is perfect for REST resources, API modules, or any group of
related endpoints.

:::info Session Access in Modular Routes When using `injectIn()` with handler
functions (`router.get('/', _handler)`), your handlers receive only a `Request`
parameter. To access the `Session`, use `request.session`:

```dart
Future<Result> _handler(Request request) async {
final session = request.session; // Extract Session from Request
// ... use session
}
```

This differs from `Route.handleCall()` which receives both Session and Request
as explicit parameters. The modular route pattern uses Relic's router directly,
which only provides Request to handlers. :::
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is perhaps the primary reason I would like to get rid of the explicit handleCall method that takes a Session.
I still think it is acceptable to have user obtain the session from request.session.

Copy link
Contributor

@SandPod SandPod left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments before discussion.

# Web server

In addition to the application server, Serverpod comes with a built-in web server. The web server allows you to access your database and business layer the same way you would from a method call from an app. This makes it very easy to share data for applications that need both an app and traditional web pages. You can also use the web server to create webhooks or generate custom REST APIs to communicate with 3rd party services.
In addition to the application server, Serverpod comes with a built-in web
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Split this page up into suitable subpages.

Perhaps the first one should be named get started or introduction?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 36606c4

Comment on lines 18 to 20
Serverpod's web server is still experimental, and the APIs may change in the
future. This documentation should give you some hints on getting started, but we
plan to add more extensive documentation as the web server matures.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should drop it. With Serverpod 3 the web server is no longer experimental :D


When you create a new Serverpod project, it sets up a web server by default. When working with the web server, there are two main classes to understand; `ComponentRoute` and `Component`. The `ComponentRoute` provides an entry point for a call to the server and returns a `Component`. The `Component` renders a web page or response using templates, JSON, or other custom means.
When you create a new Serverpod project, it sets up a web server by default.
When working with the web server, there are two main classes to understand;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: This is if someone wants to use our templating engine. Should perhaps start with registering routes and things like that? Or quickly browse through this in a get started section?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is inherited from the existing jobs (just rewrap really). I will move it to a less prominent spot.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 36606c4

Comment on lines 82 to 85
In the future, we plan to add a widget library to Serverpod with widgets
corresponding to the standard widgets used by Flutter, such as Column, Row,
Padding, Container, etc. This would make it possible to render server-side
widgets with similar code used within Flutter.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove this not to have promises in the docs. I think Jaspr is probably good enough.

- Created docs/06-concepts/18-webserver/ directory with 7 focused pages
- Added docs/01-get-started/05-web-server.md quick start guide
- Organized content by feature: routing, modular routes, middleware, static files, typed headers, server-side HTML
- De-emphasized WidgetRoute/TemplateWidget with Jaspr recommendation
- Added _category_.json for Docusaurus sidebar navigation
- Improved discoverability with navigation between related topics
- Remove experimental warnings from web server documentation
Comment on lines +5 to +9
For modern server-side HTML rendering with Serverpod, we recommend using
[Jaspr](https://docs.page/schultek/jaspr), which provides a Flutter-like API for
building web applications. You can integrate Jaspr with Serverpod's web server
using custom `Route` classes, giving you full control over request handling
while leveraging Jaspr's component model.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SandPod Something like this?

@nielsenko nielsenko requested a review from SandPod November 21, 2025 12:56
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.

3 participants