Artifact
Le panneau à côté d’un chat IA qui montre ce que le modèle a produit. Pages web, SVG, documents et code arrivent en direct, puis passent à un aperçu isolé en sandbox, avec des versions à comparer et à restaurer, une séparation redimensionnable et une bottom sheet sur mobile.
Quand un modèle produit quelque chose qui mérite d’être conservé, comme une page web, un document ou un fichier, cela a sa place à côté du chat plutôt qu’à l’intérieur. Artifact Workspace place votre chat et un panneau côte à côte. Le panneau s’ouvre tout seul quand un artifact commence à arriver en streaming, glisse pendant que le chat lui fait de la place, et peut être redimensionné, agrandi sur toute la largeur ou fermé en le faisant glisser. Sur mobile, il devient une bottom sheet qui ne s’ouvre qu’au toucher d’une carte, donc la lecture du chat n’est jamais interrompue.
Pendant que le modèle écrit, le panneau affiche du code coloré qui suit les nouvelles lignes, avec un bouton Jump to latest si vous remontez. Les pages web et les SVG passent à leur aperçu à la fin de l’écriture, jamais en cours de streaming, et l’aperçu continue d’afficher la dernière version terminée d’ici là. Les documents s’affichent en Markdown pendant le streaming. Les aperçus s’exécutent dans une iframe en sandbox sans accès à votre site, ne s’échangent qu’une fois la nouvelle version chargée pour éviter tout flash blanc, et signalent les erreurs d’exécution avec une action Fix it que vous pouvez renvoyer au modèle.
Les petits changements ne réécrivent pas le fichier. Une mise à jour peut envoyer des edits, chacun étant un rechercher-remplacer appliqué dans l’ordre à la dernière version terminée, comme les artifacts de Claude. Le code reste à l’écran et défile jusqu’à chaque modification, les lignes supprimées sont barrées puis se replient, le nouveau texte se tape avec une teinte verte, et le reste du fichier ne bouge pas. La carte indique Editing avec le nombre de changements. Une modification dont le texte est introuvable, ou trouvé plusieurs fois, fait échouer cette version avec un message indiquant quelle modification et pourquoi, et la dernière bonne version reste courante. Utilisez edits pour les changements locaux et le content complet quand la majeure partie du fichier ou sa structure change.
Chaque mise à jour est une nouvelle version. L’en-tête les liste avec ce qui a changé, Show changes compare une version à la précédente ligne par ligne avec la même vue de diff que Diff Review, et les anciennes versions peuvent être restaurées sans rien supprimer. Les compteurs d’ajouts et de suppressions à côté du bouton et sur la carte correspondent aux lignes que montre le diff. Une nouvelle version passe toujours au premier plan. Les cartes du chat affichent la version produite par leur message, donc cliquer sur une ancienne carte ouvre cette version. getArtifactsFromMessages construit tout cela à partir des appels d’outils d’AI SDK, et le panneau, la vue de code et l’aperçu fonctionnent aussi seuls.
Ajouter le registre Pro à components.json
components.json Ajouter votre token
Créez un token sur votre page de compte et placez-le dans
.env.localsous le nomHEXTAUI_PRO_TOKEN.Ajouter le block
pnpm dlx shadcn@latest add @hextaui-pro/artifact
Avec AI SDK
getArtifactsFromMessages transforme les appels d’outils create_artifact et update_artifact de useChat en artifacts avec versions. Placez un ArtifactCard là où chaque appel apparaît, et restaurez en ajoutant un appel update terminé avec setMessages. update_artifact s’exécute dans le navigateur, donc applyEdits peut signaler au modèle qu’une modification ne correspondait pas pour qu’il réessaie.
Les outils sur votre serveur
Deux outils suffisent : l’un crée un artifact avec un id stable, l’autre le modifie. Une modification est soit des edits, des paires rechercher-remplacer pour les petits changements, soit le content entier pour une réécriture. Les deux arrivent en streaming comme entrée d’outil, si bien que le panneau se remplit, ou que la modification se tape sur place, pendant que le modèle écrit.
Un panneau seul
Affiche un artifact enregistré sans chat, par exemple sur une page de partage. Le panneau garde sa propre version, son onglet et son état de comparaison.
Anatomie
Les parties à composer, de l’extérieur vers l’intérieur.
| Partie | Description |
|---|---|
ArtifactWorkspace | La mise en page : votre chat en children, le panneau à côté sur grand écran et dans une bottom sheet sur petit écran. Elle décide de ce qui est ouvert, ouvre les nouveaux artifacts et annonce la progression. |
ArtifactCard | La carte d’un message qui ouvre un artifact, ou l’une de ses versions, et qui indique s’il est en cours d’écriture, en échec ou ouvert. |
ArtifactPanel | L’en-tête avec titre, versions, onglets et actions, et en dessous le code, les changements, l’aperçu ou le document. |
ArtifactCode, ArtifactPreview | La vue de code et de diff en streaming, et l’aperçu en sandbox avec sa carte d’erreur. |
getArtifactsFromMessages, applyEdits | Lit les appels d’outils de création et de mise à jour dans les messages AI SDK et renvoie les artifacts avec leurs versions. applyEdits applique de la même façon les modifications rechercher-remplacer, ce qui permet de vérifier une modification avant de dire au modèle qu’elle a fonctionné. |
useArtifactWorkspace | Ouvre et ferme des artifacts depuis vos propres contrôles, par exemple une liste de fichiers dans une barre latérale. |
| Prop | Type | Par défaut |
|---|---|---|
artifactsChaque artifact de la conversation, dans l’ordre. En général getArtifactsFromMessages(messages). | Artifact[] | – |
childrenLe chat, généralement un ChatThread. | ReactNode | – |
openIdL’artifact ouvert, lorsque vous le contrôlez. Un id absent de artifacts compte comme fermé. | string | null | – |
defaultOpenIdL’artifact ouvert au départ, en mode non contrôlé. | string | null | null |
onOpenChangeAppelé à l’ouverture d’un artifact ou à la fermeture du panneau. | (id: string | null) => void | – |
autoOpenOuvre un artifact sur grand écran quand une version commence à arriver en streaming. Il s’ouvre une fois par version, jamais après que vous l’avez fermé pendant ce streaming, et ne déplace jamais le focus. | boolean | true |
defaultPanelSizePart de la largeur occupée par le panneau, en pourcentage, à son ouverture. Le chat garde au moins 320px et le panneau au moins 360px. Faire glisser le séparateur l’emporte pour le reste de la session. | number | 70 |
onRestoreAffiche Restore sur les anciennes versions. Ajoute l’ancien contenu comme nouvelle version ; rien n’est supprimé. | (artifact, version) => void | – |
onFixAffiche Fix it quand l’aperçu lève une erreur. error contient message et line. | (artifact, version, error) => void | – |
actionsContrôles d’en-tête supplémentaires, comme Publish ou Share. | (artifact) => ReactNode | – |
| Prop | Type | Par défaut |
|---|---|---|
artifactIdL’artifact à ouvrir. N’affiche rien s’il n’existe pas. | string | – |
versionIdLa version que représente cette carte, généralement l’id de l’appel d’outil. Un clic ouvre cette version, et la carte indique de laquelle il s’agit. | string | – |
ArtifactPanel
Rendu pour vous dans ArtifactWorkspace. Utilisez-le directement pour afficher un artifact sans chat.
| Prop | Type | Par défaut |
|---|---|---|
artifactCe qu’il faut afficher. | Artifact | – |
versionIdLa version affichée, lorsque vous la contrôlez. null suit la version la plus récente. | string | null | – |
onVersionChangeAppelé quand quelqu’un choisit une version, avec null pour la plus récente. | (versionId: string | null) => void | – |
onCloseAffiche le bouton de fermeture et ferme avec Escape. | () => void | – |
fullscreen, onFullscreenChangeAffiche Expand et Show chat, et quitte le mode agrandi avec Escape. | boolean, (fullscreen: boolean) => void | – |
onRestore, onFix, actionsIdentique à celui du workspace. | see ArtifactWorkspace | – |
Artifact
Les données lues par les composants.
| Prop | Type | Par défaut |
|---|---|---|
id, titleUn identifiant stable et le titre affiché dans l’en-tête et la carte. | string | – |
kindhtml et svg obtiennent un aperçu en sandbox, markdown s’affiche comme un document, code n’affiche que le code. | "html" | "svg" | "markdown" | "code" | – |
language, filenameColoration et nom de téléchargement pour le code. | string | – |
versionsLes plus anciennes d’abord. status vaut streaming, complete, stopped ou error ; note indique ce qui a changé. edits liste les paires rechercher-remplacer qu’une mise à jour ciblée a appliquées ; content est toujours le résultat complet. | { id, content, status?, error?, note?, edits?, createdAt?, messageId? }[] | – |
| Prop | Type | Par défaut |
|---|---|---|
messagesMessages de useChat. Les appels d’outils nommés create_artifact et update_artifact, ou leurs formes en camelCase, deviennent des versions. | UIMessage[] | – |
options.streamingIndique si le dernier message est encore en cours d’arrivée. Sans cela, les appels inachevés comptent comme interrompus. | boolean | false |
options.toolsLes noms de vos propres outils. Create lit id, title, kind, language, filename, description et content. Update lit id, description et soit content, soit edits. | { create: string[]; update: string[] } | – |
update inputcontent réécrit l’artifact. edits s’appliquent dans l’ordre à la dernière version terminée ; chaque find doit correspondre exactement une fois, sinon la version échoue avec error indiquant quelle modification et pourquoi. Si les deux sont envoyés, content l’emporte. | { content: string } | { edits: { find: string; replace: string }[] } | – |
| Touche | Action |
|---|---|
| Enter | Sur une carte, ouvre son artifact et place le focus sur le titre du panneau. Sur une carte ouverte, la ferme. |
| Esc | Quitte le mode agrandi, puis ferme le panneau et rend le focus à la carte. |
| ←→ | Redimensionne la séparation tant que le séparateur a le focus. Au-delà de la plus petite taille, le panneau se ferme ou le chat se masque. |
| ←→ | Bascule entre Code et Preview quand un onglet a le focus. |
| Tab | Parcourt l’en-tête, la zone de code ou de document, qui défile avec les flèches du clavier, et l’aperçu. |
- Le panneau est une région libellée avec un vrai titre. L’ouvrir depuis une carte place le focus sur ce titre, et le fermer rend le focus à la carte. Quand il s’ouvre tout seul pendant que le modèle écrit, il ne déplace jamais le focus, donc la saisie dans le champ de message n’est jamais interrompue.
- Les cartes sont des boutons avec aria-pressed et aria-controls, et indiquent si l’artifact est en cours d’écriture, en échec ou interrompu. Un statut poli annonce le début de l’écriture et la disponibilité d’une version, au lieu de lire chaque ligne.
- L’iframe d’aperçu porte le titre de l’artifact. Les erreurs d’exécution apparaissent sous forme d’alerte avec le message et la ligne, comme une modification qui n’a pas pu être appliquée. Les changements sont annoncés comme ajoutés et supprimés, pas seulement montrés en couleur.
- Chaque bouton d’icône a un libellé et une infobulle. L’ouverture, la fermeture et l’agrandissement glissent pendant que le chat se réagence en douceur ; avec réduction des animations, la mise en page change d’un coup avec un court fondu. Les modifications apparaissent en fondu d’un bloc au lieu d’être tapées.
Construit avec
Les composants HextaUI gratuits dont Artifact est constitué. Chacun s’installe séparément.
Code
12 fichiers, ajoutés à components/blocks/artifact.