---
title: "D’une vue au HTML progressif"
headingIds:
  [
    "from-a-view-to-progressive-html",
    "set-up-jsx",
    "compose-a-view",
    "return-html-from-a-route",
    "let-the-results-arrive-later",
    "continue-from-here",
  ]
---

# D’une vue au HTML progressif

Construisez d’abord une vue serveur, puis ajoutez les fragments progressifs aux parties qui en bénéficient.

## Configurer le JSX

Installez Core et configurez le JSX avec `jsxImportSource: "@vincle/core"`.

## Composer une vue

Les composants sont des fonctions. Composez-les avec des props typées et chargez les données dans les composants `async`.

```tsx title="results.tsx"
// Replace this sample data source with your database or search service.
async function findResults() {
  return [{ title: "Getting started", href: "/guide/getting-started/installation" }];
}

export async function Results() {
  const items = await findResults();
  return (
    <ul>
      {items.map((item) => (
        <li>
          <a href={item.href}>{item.title}</a>
        </li>
      ))}
    </ul>
  );
}
```

## Retourner du HTML depuis une route

Attendez `renderToString` et retournez une réponse `text/html`. Votre routeur reste responsable des requêtes et des réponses.

```tsx
import { renderToString } from "@vincle/core";
import { Results } from "./results";

export async function GET() {
  const html = await renderToString(
    <main>
      <h1>Search results</h1>
      <Results />
    </main>,
  );

  return new Response(html, {
    headers: { "Content-Type": "text/html; charset=utf-8" },
  });
}
```

## Laisser arriver les résultats plus tard

Installez Flow pour différer les résultats lents. `serve()` négocie le mode de réponse ; `<Defer>` conserve un contenu de repli jusqu’à l’arrivée du fragment.

```bash tab="npm" sync="pkg-manager"
npm install @vincle/flow
```

```bash tab="pnpm" sync="pkg-manager"
pnpm add @vincle/flow
```

```bash tab="bun" sync="pkg-manager"
bun add @vincle/flow
```

```tsx
import { Defer, renderToStream } from "@vincle/flow";
import { NativeAdapter } from "@vincle/flow/adapters";
import { Results } from "./results";

function Page() {
  return (
    <main>
      <h1>Search results</h1>
      <Defer fallback={<p>Loading results…</p>}>
        <Results />
      </Defer>
    </main>
  );
}

const stream = renderToStream(() => <Page />, NativeAdapter);
```

```tsx
return new Response(stream.pipeThrough(new TextEncoderStream()), {
  headers: { "Content-Type": "text/html; charset=utf-8" },
});
```

## Pour aller plus loin

Consultez les [composants](/fr/guide/jsx/components), le [streaming](/fr/integration/streaming) et le [service HTTP](/fr/integration/http-serving).
