Server-Side HTML
For simple HTML pages, you can use WidgetRoute and TemplateWidget. The
WidgetRoute provides an entry point for handling requests and returns a
WebWidget. The TemplateWidget (which extends WebWidget) renders web pages
using Mustache templates.
Creating a WidgetRoute
Create custom routes by extending the WidgetRoute class and implementing the
build method:
class MyRoute extends WidgetRoute {
Future<TemplateWidget> build(Session session, Request request) async {
return MyPageWidget(title: 'Home page');
}
}
// Register the route
pod.webServer.addRoute(MyRoute(), '/my/page/address');
Creating a TemplateWidget
A TemplateWidget consists of a Dart class and a corresponding HTML template
file. Create a custom widget by extending TemplateWidget:
class MyPageWidget extends TemplateWidget {
MyPageWidget({required String title}) : super(name: 'my_page') {
values = {
'title': title,
};
}
}
Place the corresponding HTML template in the web/templates directory. The HTML
file uses the Mustache template language:
<!DOCTYPE html>
<html>
<head>
<title>{{title}}</title>
</head>
<body>
<h1>{{title}}</h1>
<p>Welcome to my page!</p>
</body>
</html>
Template values are converted to String objects before being passed to the
template. This makes it possible to nest widgets, similarly to how widgets work
in Flutter.
Built-in widgets
Serverpod provides several built-in widgets for common use cases:
-
ListWidget- Concatenates multiple widgets into a single responsereturn ListWidget(children: [
HeaderWidget(),
ContentWidget(),
FooterWidget(),
]); -
JsonWidget- Renders JSON documents from serializable data structuresreturn JsonWidget({'status': 'success', 'data': myData}); -
RedirectWidget- Creates HTTP redirects to other URLsreturn RedirectWidget('/new/location');
Database access and logging
The web server passes a Session object to the WidgetRoute class' build
method. This gives you access to all the features you typically get from a
standard method call to an endpoint. Use the database, logging, or caching the
same way you would in a method call:
class DataRoute extends WidgetRoute {
Future<TemplateWidget> build(Session session, Request request) async {
// Access the database
final users = await User.db.find(session);
// Logging
session.log('Rendering user list page');
return UserListWidget(users: users);
}
}
If you prefer 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.
Next steps
- For modern server-side rendering, explore Jaspr integration
- Use custom routes for REST APIs and custom request handling
- Serve static files for CSS, JavaScript, and images
- Add middleware for cross-cutting concerns like logging and error handling