Routing
In modern web applications, routing refers to the process of managing navigation between different views or components based on the current URL or path. In webforJ, routing establishes a sophisticated framework for client-side navigation, where UI updates happen dynamically without requiring full page reloads, enhancing the performance of your app.
Traditional vs client-side routing
In traditional server-side routing, when a user clicks a link, the browser sends a request to the server for a new document. The server responds by sending a fresh HTML page, which forces the browser to re-evaluate CSS and JavaScript, re-render the entire document, and reset the app state. This cycle introduces delays and inefficiencies, as the browser must reload resources and the page state. The process typically involves:
- Request: The user navigates to a new URL, triggering a request to the server.
- Response: The server sends back a new HTML document along with related assets (CSS, JS).
- Rendering: The browser re-renders the entire page, often losing the state of previously loaded pages.
This approach can lead to performance bottlenecks and suboptimal user experiences due to repeated full-page reloads.
Client-Side Routing in webforJ solves this by enabling navigation directly in the browser, dynamically updating the UI without sending a new request to the server. Here's how it works:
- Single Initial Request: The browser loads the app once, including all required assets (HTML, CSS, JavaScript).
- URL Management: The router listens for URL changes and updates the view based on the current route.
- Dynamic Component Rendering: The router maps the URL to a component and renders it dynamically, without refreshing the page.
- State Preservation: The state of the app is maintained between navigations, ensuring smooth transition between views.
This design enables deep linking and URL-driven state management, allowing users to bookmark and share specific pages within the app while enjoying a smooth, single-page experience.
Core principles
- URL-Based Component Mapping: In webforJ, routes are directly tied to UI components. A URL pattern is mapped to a specific component, dictating what content is displayed based on the current path.
- Declarative Routing: Routes are defined declaratively, typically using annotations. Each route corresponds to a component that is rendered when the route is matched.
- Dynamic Navigation: The router dynamically switches between views without reloading the page, keeping the app responsive and fast.
Example of client-side routing in webforJ
Here’s an example of defining a route for a UserProfileView
component to display user details based on the id
parameter in the URL:
@Route(value = "user/:id")
public class UserProfileView extends Composite<Div> implements DidEnterObserver {
@Override
public void onDidEnter(DidEnterEvent event, ParametersBag parameters) {
String id = parameters.getAlpha("id").orElse("");
refreshProfile(id);
}
}
In this setup:
- Navigating to
/user/john
would render theUserProfileView
component. - The
id
parameter would capturejohn
from the URL and allow you to use it within the component to fetch and display user data.
Topics
📄️ Routable Apps
Routing in webforJ is an optional tool. Developers can choose between the webforJ routing solution or a traditional model with Frame manipulation and without deep linking. To enable routing, the @Routify annotation must be applied at the level of a class implementing App. This grants webforJ the authority to manage browser history, respond to navigation events, and render the app’s components based on the URL.
📄️ Defining Routes
Defining routes is essential for mapping URLs to specific components. This allows you to control how different parts of your UI are rendered based on the URL structure. The framework uses the @Route annotation to make this process declarative and straightforward, reducing the need for manual configuration.
📄️ Route Navigation
In webforJ, navigating between routes is the core mechanism for switching views and components based on user actions or URL changes. Navigation allows users to move seamlessly between different parts of the app without refreshing the page. This client-side navigation keeps the app responsive and smooth while preserving the app's state.
📄️ Route Patterns
Route Patterns are used to define how URLs map to specific views, including dynamic and optional segments, regular expressions, and wildcards. Route patterns enable the framework to match URLs, extract parameters, and generate URLs dynamically. They play a critical role in structuring an app's navigation and component rendering based on the browser's location.
📄️ Query Parameters
Query parameters allow you to pass additional data through URLs, using the format ?key1=value1&key2=value2. While route parameters are used to pass required data within the URL path, query parameters provide a flexible mechanism for passing optional or additional data. They're especially useful when filtering content, sorting, or handling multiple values for the same key.
📄️ State Management
Creating seamless, dynamic user experiences often requires that the state of your web app be reflected in the URL and retained across browser navigation events. You can achieve this without reloading the page by leveraging URL parameter updates and browser history state management. This ensures that users can share, bookmark, or return to specific views with the app fully aware of their prior interactions.
🗃️ Navigation Lifecycle
3 items
🗃️ Route Hierarchy
3 items
📄️ Navigational Frame Titles
In webforJ, all routes are rendered within a Frame, which serves as a top-level container responsible for displaying the content of the current route. As users navigate between different routes, the Frame Title is updated dynamically to reflect the active view, helping provide clear context on the user's current location within the app.
📄️ Routes Registration
In addition to registering routes using the @Route annotations, it's possible to dynamically register, update, or remove routes at runtime based on app logic, user roles, or other conditions. This flexibility enables you to manage navigation more dynamically, rather than statically defining routes at compile time.