Introduction
Dans l’article Svelte, routage sans déroute, on avait vu comment mettre en place le routage au sein d’une application SPA. Sauf qu’il y a un petit souci: ce type de routage fonctionne sous Node.js ou en « Server Side Rendering ». Comment faire quand on doit utiliser un serveur Web/J2EE?
Svelte: mise en place du routage
On va utiliser ici la librairie « svelte routing » (documentation sur GitHub: https://github.com/EmilTholin/svelte-routing). L’installation se fait via NPM:
npm install --save svelte-routing
Ensuite, dans la page principale Svelte, on ajoute ces éléments (en jaune):
<style></style>
<script>
import { Router, Link, Route } from "svelte-routing";
import CmpLfdUserLogin from "./cmpLfdUserLogin.svelte";
import CmpLfdUserRegister from "./cmpLfdUserRegister.svelte";
export let urlSpa = '/app/spa/login';
</script>
<main class="hero is-fullheight">
<div class="hero-body">
<div class="container">
<p class="title">
<Router url="{urlSpa}">
<Route path="/app/spa/login"><CmpLfdUserLogin /></Route>
<Route path="/app/spa/register"><CmpLfdUserRegister /></Route>
</Router>
</p>
</div>
</div>
</main>
On peut bien sûr ajouter autant de tag <Route>
que nécessaire: il suffit d’inclure le composant lié et de gérer l’url dédiée. Ensuite, pour changer de page (en fait le composant puisque le serveur TomEE n’est pas mis à contribution), il faut faire un navigate(url, { replace: true });
Le navigateur affiche alors l’url demandée (exemple: http://serveur/app/spa/login).
TomEE: redirection SPA
Une fois qu’on a navigué vers la page avec navigate
, on croit que tout va bien. Mais si on recharge la page, le browser va effectuer une requête auprès du serveur (dans notre exemple, le serveur va devoir servir la page /app/spa/login). Sauf que cette url n’est pas connue de la WebApp et notre serveur TomEE retourne une erreur 404. On va donc rediriger les urls de type /app/spa vers la page d’accueil de l’application en lui indiquant quel est le composant demandé.
Pour rediriger les urls dans TomEE, il y a 3 petites étapes à effectuer: ajouter une dépendance au pom.xml, configurer le web.xml et ajouter la configuration des redirections dans le fichier WEB-INF/urlrewrite.xml.
pom.xml
On va ajouter le package org.tuckey.urlrewritefilter. La documentation se trouve sur http://www.tuckey.org/urlrewrite/.
<dependency>
<groupId>org.tuckey</groupId>
<artifactId>urlrewritefilter</artifactId>
<version>4.0.4</version>
</dependency>
web.xml
On ajoute un filtre qui se chargera de rediriger les urls configurées.
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
WEB-INF/urlrewrite.xml
<urlrewrite>
<rule>
<note>Transfer all urls starting with /spa/ to index page so client can route itselfs correctly</note>
<from>/spa/(.*)</from>
<to type="redirect">%{context-path}/index.html?page=/app/spa/$1</to>
</rule>
</urlrewrite>
Ici, %{context-path}
représente l’url de base de la WebApp (/app/ dans notre exemple).
Svelte: interception de la redirection
Dans notre composant principal, on va lire le paramètre « page » dans le QueryString de l’url (3 cas: paramètre manquant, sans valeur et avec valeur). Les modifications sont en jaune.
<style></style>
<script>
import { Router, Link, Route } from "svelte-routing";
import CmpLfdUserLogin from "./cmpLfdUserLogin.svelte";
import CmpLfdUserRegister from "./cmpLfdUserRegister.svelte";
let urlParams = new URLSearchParams(window.location.search);
let page = urlParams.get('page');
export let urlSpa = ((null !== page) && (0 < page.trim().length)? page : '/app/spa/login'); // ici, si on a un paramètre "page" valide, on l'utilise sinon on va à la page de login.
</script>
<main class="hero is-fullheight">
<div class="hero-body">
<div class="container">
<p class="title">
<Router url="{urlSpa}">
<Route path="/app/spa/login"><CmpLfdUserLogin /></Route>
<Route path="/app/spa/register"><CmpLfdUserRegister /></Route>
</Router>
</p>
</div>
</div>
</main>
Conclusion
Moyennant peu de code, il est facile d’héberger une application « Single Page App » réalisée avec Svelte.
Illustration: Photo by Alex Kalinin on Unsplash