# Intégration collaborative

> Connecter l’éditeur Univer à un service collaboratif pour modifier un même document à plusieurs.

- Human documentation: [https://docs.univer.ai/fr-FR/server/collaboration/browser-integration](https://docs.univer.ai/fr-FR/server/collaboration/browser-integration)

- Agent Markdown: [https://docs.univer.ai/fr-FR/server/collaboration/browser-integration.md](https://docs.univer.ai/fr-FR/server/collaboration/browser-integration.md)

- Requested language: `fr-FR`

- Content language: `fr-FR`

- Documentation version: `1.2.0`

- Source: [collaboration/browser-integration.fr-FR.mdx](https://github.com/dream-num/documentation/blob/dev/content/server/collaboration/browser-integration.fr-FR.mdx)

---

La collaboration connecte les éditeurs du navigateur à un service de documents partagés. Par exemple, deux utilisateurs ouvrent le même classeur et une modification dans un navigateur apparaît dans l’autre.

Préparez le backend avec l’[intégration serveur](https://docs.univer.ai/fr-FR/server.md), puis configurez l’éditeur et le chargement ci-dessous. Suivez ensemble les codes Server et Web du [Démarrage rapide de la collaboration](https://docs.univer.ai/fr-FR/server/collaboration/quick-start.md).

```mermaid
flowchart LR; A["Éditeur utilisateur A"] <-->|Échange des modifications| S["Service collaboratif"]; S <-->|Échange des modifications| B["Éditeur utilisateur B"]; S --> D[("Enregistrer les documents")];
```

## Connecter votre éditeur existant

Conservez votre éditeur Web SDK. Suivez la [configuration navigateur du démarrage rapide](https://docs.univer.ai/fr-FR/server/collaboration/quick-start.md) pour ajouter les plugins collaboratifs et configurer le chargement, l’envoi de modifications et les adresses WebSocket. Gardez les versions des paquets navigateur et serveur compatibles.

Les utilisateurs fixes et les autorisations par défaut des exemples servent à la démonstration. Dans votre application, joignez les identifiants de connexion aux requêtes pour que le backend vérifie l’identité et l’accès au document. Consultez la [configuration de la licence](https://docs.univer.ai/fr-FR/server/license.md) pour la licence.

## Créer et ouvrir le même document

La création et l’ouverture sont deux actions distinctes :

1. Lorsqu’un utilisateur crée un document, votre backend l’enregistre et renvoie son ID.
2. Le navigateur charge cet ID. Réutilisez-le pour rouvrir le document ou le partager.

Le `unitId` de l’API est cet ID de document. Ne créez pas un nouveau document local vierge à chaque visite.

Définissez l’utilisateur courant avant de charger un document. Il identifie le collaborateur et possède le cache hors ligne local ; voir [Identité et autorisations](https://docs.univer.ai/fr-FR/server/collaboration/identity-and-authorization.md).

Par exemple, après avoir enregistré les plugins Sheets et collaboratifs, chargez un classeur du serveur :

```ts
import { UserManagerService } from '@univerjs/core'
import '@univerjs-pro/collaboration-client/facade'

univer.__getInjector().get(UserManagerService).setCurrentUser({ userID, name, avatar })

const workbook = await univerAPI.getCollaboration().loadSheetAsync('your-document-id')
if (!workbook) throw new Error('Document could not be loaded')
```

Consultez les guides [Sheets](https://docs.univer.ai/fr-FR/guides/sheets/features/collaboration.md), [Docs](https://docs.univer.ai/fr-FR/guides/docs/features/collaboration.md), [Slides](https://docs.univer.ai/fr-FR/guides/slides/features/collaboration.md), [Boards](https://docs.univer.ai/fr-FR/guides/boards/features/collaboration.md), [Bases](https://docs.univer.ai/fr-FR/guides/bases/features/collaboration.md) et [PDFs](https://docs.univer.ai/fr-FR/guides/pdfs/features/collaboration.md) pour le chargement propre à chaque produit. Vérifiez la prise en charge par le produit et la version backend ciblée.

## Vérifier synchronisation, enregistrement et autorisations

Ouvrez le même document dans deux sessions indépendantes, par exemple une fenêtre normale et une privée. Modifiez dans l’une et vérifiez l’autre. Vérifiez ensuite le contenu après actualisation, reconnexion et redémarrage serveur.

Testez avec un éditeur, un lecteur et un utilisateur non autorisé. Les réglages UI de lecture seule contrôlent les interactions ; le serveur doit toujours refuser les lectures et changements non autorisés.

Si les documents se chargent mais que les modifications ne se synchronisent pas, vérifiez WebSocket. Si le contenu disparaît au redémarrage, vérifiez le stockage backend. Ces réglages sont décrits dans l’[intégration serveur](https://docs.univer.ai/fr-FR/server.md).

## Ajouter échange de fichiers, commentaires ou historique

Pour modifier ensemble un fichier importé, créez un document collaboratif à partir des données converties ; consultez l’[intégration de l’échange de fichiers](https://docs.univer.ai/fr-FR/server/import-export.md). Commentaires et historique nécessitent leurs propres plugins, services et autorisations. Suivez les [modules d’extension Office](https://docs.univer.ai/fr-FR/server/collaboration/extensions.md).

Pour les panneaux d’historique, consultez [Sheets](https://docs.univer.ai/fr-FR/guides/sheets/features/edit-history.md), [Docs](https://docs.univer.ai/fr-FR/guides/docs/features/edit-history.md), [Slides](https://docs.univer.ai/fr-FR/guides/slides/features/edit-history.md), [Boards](https://docs.univer.ai/fr-FR/guides/boards/features/edit-history.md) et [Bases](https://docs.univer.ai/fr-FR/guides/bases/features/edit-history.md). La portée actuelle pour PDFs est décrite dans [Historique PDFs](https://docs.univer.ai/fr-FR/guides/pdfs/features/edit-history.md).

## État de synchronisation et renvois

Après import du Facade, `CollaborationStatusChanged` signale l’état courant des documents déjà collaboratifs lors de l’abonnement, puis les changements sans doublons consécutifs. `hasWritePending(unitId)` inclut les modifications en attente d’envoi, d’accusé de réception et hors ligne. Sans ID, il vérifie le document ciblé. Une connexion ouverte ne signifie pas que tout est enregistré.

```ts
import '@univerjs-pro/collaboration-client/facade'

const collaboration = univerAPI.getCollaboration()
const statusSubscription = univerAPI.addEvent(univerAPI.Event.CollaborationStatusChanged, (event) => {
  console.info(event.unitId, event.status, collaboration.hasWritePending(event.unitId))
})
const resendSubscription = univerAPI.addEvent(univerAPI.Event.CollaborationChangesetResend, (event) => {
  console.info(event.unitId, event.reason, event.attempt, event.unsyncedMutationCount, event.nextDelayMs)
})
```

`CollaborationChangesetResend` intervient uniquement lors des renvois. Les raisons sont `ack_timeout`, `should_retry` et `reconnect`. `attempt`, `elapsedMs`, `unsyncedMutationCount` et `nextDelayMs` permettent d’afficher l’enregistrement et les tentatives. Libérez les abonnements à la suppression de l’éditeur.

Le délai de regroupement diffère du délai d’accusé de réception. Valeurs du plugin en millisecondes : `sendChangesetTimeout: 2000`, `changesetAckTimeout: 20000`, `maxChangesetAckTimeout: 120000`. La requête d’envoi utilise aussi le délai d’accusé. Sans confirmation, les renvois suivent un recul exponentiel jusqu’au maximum. Deux délais d’accusé identiques donnent un intervalle constant.

```ts
import { UniverCollaborationClientPlugin } from '@univerjs-pro/collaboration-client'
import { BrowserCollaborationSocketService } from '@univerjs-pro/collaboration-client-ui'

univer.registerPlugin(UniverCollaborationClientPlugin, {
  socketService: BrowserCollaborationSocketService,
  sendChangesetTimeout: 200,
  changesetAckTimeout: 20_000,
  maxChangesetAckTimeout: 120_000,
})
```

Ajoutez ces options à l’enregistrement existant en conservant socket et endpoints. Les presets collaboratifs Sheets et Docs utilisent un regroupement de 200 ms et n’exposent pas les délais d’accusé ; utilisez le mode plugin pour les personnaliser.

## Gérer les conflits dans l’application

`CollaborationConflict` intervient une fois à l’entrée en conflit, après la tentative de nettoyage du cache hors ligne. Abonnez-vous avant le chargement. `reason` vaut `transform_failed`, `apply_failed`, `changeset_rejected`, `permission_rejected` ou `remote_revert` ; `message` et `revert` apportent des détails si disponibles.

```ts
import type { IEventParamConfig } from '@univerjs/core/facade'
import '@univerjs-pro/collaboration-client/facade'

const conflicts = new Map<string, IEventParamConfig['CollaborationConflict']>()
const conflictSubscription = univerAPI.addEvent(univerAPI.Event.CollaborationConflict, (event) => {
  conflicts.set(event.unitId, event)
})
```

L’exemple conserve l’événement pour un écran de récupération. La Map reste en mémoire : avant de recharger, enregistrez ou exportez `localChanges` dans l’application. C’est lors de cet événement qu’il faut les retenir ; le cache effacé n’est plus récupérable ensuite. `awaitingChangeset` a peut-être déjà été appliqué sur le serveur : ne le rejouez pas aveuglément.

Avec `cacheCleared: false`, recharger rejouerait les anciennes modifications du cache. Résolvez le nettoyage avant de recharger. Effacer le cache ne confirme pas la sauvegarde des modifications. `permission_rejected` exige aussi de résoudre l’accès ; recharger ne donne aucun droit.

Par défaut, l’UI affiche une notification selon la raison et propose de recharger après nettoyage réussi, ou de réessayer si le nettoyage échoue. Pour gérer la récupération vous-même, définissez `enableDefaultConflictUI: false` dans l’initialisation existante et traitez l’événement :

#### Mode plugin

```ts
import { UniverCollaborationClientUIPlugin } from '@univerjs-pro/collaboration-client-ui'

univer.registerPlugin(UniverCollaborationClientUIPlugin, { enableDefaultConflictUI: false })
```

#### Preset Sheets

```ts
import { UniverSheetsCollaborationPreset } from '@univerjs/preset-sheets-collaboration'

const collaborationPreset = UniverSheetsCollaborationPreset({ enableDefaultConflictUI: false })
```

#### Preset Docs

```ts
import { UniverDocsCollaborationPreset } from '@univerjs/preset-docs-collaboration'

const collaborationPreset = UniverDocsCollaborationPreset({ enableDefaultConflictUI: false })
```

Ajoutez le preset collaboratif à `createUniver({ presets: [...] })` avec celui de l’éditeur, en conservant les endpoints et l’historique. Voir les [paramètres d’événement](https://docs.univer.ai/fr-FR/reference/facade/events.md#collaborationconflict) et la [configuration client](https://docs.univer.ai/fr-FR/reference/packages/plugins/univerjs-pro/collaboration-client.md).
