Piège

renderToString ne prend en charge ni le streaming ni l’attente du chargement de données. Découvrez les alternatives.

renderToString fait le rendu d’un arbre React sous forme de texte HTML.

const html = renderToString(reactNode, options?)

Référence

renderToString(reactNode, options?)

Côté serveur, appelez renderToString pour produire le HTML de votre appli.

import { renderToString } from 'react-dom/server';

const html = renderToString(<App />);

Côté client, appelez hydrateRoot pour rendre interactif ce HTML généré côté serveur.

Voir d’autres exemples ci-dessous.

Paramètres

  • reactNode : un nœud React dont vous souhaitez produire le HTML. Ça pourrait par exemple être un élément JSX tel que <App />.
  • options optionnelles : un objet avec des options pour le rendu côté serveur.
    • identifierPrefix optionnel : un préfixe textuel utilisé pour les ID générés par useId. Pratique pour éviter les conflits entre les ID au sein de racines multiples sur une même page.

Valeur renvoyée

Une chaîne de caractères contenant le HTML.

Limitations

  • renderToString n’a qu’une prise en charge limitée de Suspense. Si votre composant suspend, renderToString renverra immédiatement le HTML de son JSX de secours.

  • renderToString fonctionne côté navigateur, mais nous déconseillons de l’utiliser côté client.


Utilisation

Produire le HTML d’un arbre React sous forme d’une chaîne de caractères

Appelez renderToString pour produire le texte HTML de votre appli, que vous pourrez alors renvoyer dans votre réponse serveur :

import { renderToString } from 'react-dom/server';

// La syntaxe du gestionnaire de route dépend de votre
// framework côté serveur
app.use('/', (request, response) => {
const html = renderToString(<App />);
response.send(html);
});

Ça produira le HTML initial, non interactif, de vos composants React. Côté client, vous aurez besoin d’appeler hydrateRoot pour hydrater ce HTML généré côté serveur et le rendre interactif.

Piège

renderToString ne prend en charge ni le streaming ni l’attente du chargement de données. Découvrez les alternatives.


Alternatives

Migrer de renderToString vers une méthode de streaming côté serveur

renderToString renvoie immédiatement un texte, elle ne prend donc en charge ni le streaming ni la suspension pour chargement de données.

Autant que possible nous conseillons d’utiliser plutôt une de ces alternatives plus capables :

Vous pouvez continuer avec renderToString si votre environnement serveur ne prend pas en charge les flux.


Retirer renderToString du code côté client

Il arrive que renderToString soit utilisée côté client pour convertir un composant en HTML.

// 🚩 Inutile : utilisation de renderToString côté client
import { renderToString } from 'react-dom/server';

const html = renderToString(<MyIcon />);
console.log(html); // Par exemple "<svg>...</svg>"

L’import de react-dom/server côté client augmente pour rien la taille de votre bundle, nous vous le déconseillons donc. Si vous avez besoin d’obtenir côté client le HTML d’un composant, utilisez createRoot puis lisez le HTML directement depuis le DOM :

import { createRoot } from 'react-dom/client';
import { flushSync } from 'react-dom';

const div = document.createElement('div');
const root = createRoot(div);
flushSync(() => {
root.render(<MyIcon />);
});
console.log(div.innerHTML); // Par exemple "<svg>...</svg>"

L’appel à flushSync est nécessaire pour que le DOM soit bien mis à jour avant de lire la propriété innerHTML.


Dépannage

Quand un composant suspend, le HTML reflète la version de secours

renderToString ne prend pas pleinement en charge Suspense.

Si un composant suspend (il est par exemple défini via lazy ou charge des données), renderToString n’attendra pas l’aboutissement du traitement. renderToString cherchera plutôt le périmètre <Suspense> parent le plus proche et affichera le HTML de sa prop fallback. Le contenu n’apparaîtra pas jusqu’à ce que le code client soit chargé.

Pour résoudre ça, utilisez une de nos solutions recommandées de streaming. Elles peuvent streamer le contenu par morceaux au fil de l’aboutissement des traitements côté serveur, afin que l’utilisateur puisse bénéficier d’un chargement progressif de la page avant même que le code client ne soit chargé.