Hoppa till innehållet
Sonenta

SDK · Utvärdering av slutanvändare

Förhandsversion

@sonenta/feedback

Låt dina egna slutanvändare betygsätta (5★) och föreslå översättningar inifrån din publicerade app. Ett paket, fem ingångspunkter — /react, /native, /vue, /svelte, /core — samma wire, samma serversidigt skapade session, samma back office för moderering. React & React Native kopplas in i den @sonenta/*-i18n-provider du redan kör (ingen andra kontext, ingen omrendering av värden); Vue & Svelte är idiomatiska fristående adaptrar. Tillgängligt som ett betaltillägg från Pro och uppåt.

Paketet @sonenta/feedback levereras med tillägget ”Slutanvändarutvärdering av översättningar” vid Sonentas V1-lansering. Det finns ännu inte på npm — wire-kontraktet är fryst (v3); ramverksbindningarna stabiliseras och kan fortfarande ändras före lanseringen.

1. Installera (vid lansering)

Ett enda paket. Importera ingångspunkten för ditt ramverk: @sonenta/feedback/react, /native (RN/Expo), /vue, /svelte, eller /core för allt annat. vue / svelte är valfria peer deps — bara den matchande ingångspunkten behöver dem. Publiceras med tillägget vid V1-lanseringen.

terminal
1// ships with the End-user evaluation add-on at the V1 launch2npm i @sonenta/react-i18next @sonenta/feedback3// feedback peers with @sonenta/react-i18next 2.x4// optional peer deps only for the matching entry: vue · svelte

2. React (webb) — i18n-plugin

Lägg till feedbackPlugin() i plugins-platsen i din befintliga @sonenta/react-i18next (>= 0.7.0)-provider — ingen ny provider, ingen andra kontext. Providern anropar pluginens setup() en gång och återanvänder sina egna apiBase / projectId / defaultLocale. Panelen monteras som ett isolerat syskonblad med en privat öppen/stäng-store, så att öppna den omrenderar aldrig ditt värdträd. Utlös från din egen CTA via kontrollern som levereras genom controllerRef (eller callbacken onReady).

main.tsx
1// src/main.tsx — plugin of the i18n provider you already run2import { SonentaProvider } from "@sonenta/react-i18next";3import { feedbackPlugin } from "@sonenta/feedback/react";4import { useRef } from "react"; 6const feedback = useRef(null); 8<SonentaProvider9  projectUuid="proj_xxx"10  token={import.meta.env.VITE_SONENTA_TOKEN}11  plugins={[ feedbackPlugin({ controllerRef: feedback }) ]}12>13  <App />14</SonentaProvider> 16// own CTA — does NOT re-render the host tree17<button onClick={() => feedback.current?.open()}>Rate translations</button>
Alla alternativ för feedbackPlugin() / createFeedback()
Alternativ Typ Standard
controllerRefRef<Controller>
onReady(c) => void
keysstring[]auto-discovered
flushDebounceMsnumber1500
maxBatchnumber20
defaultButtonbooleanfalse

3. React Native / Expo

Identiskt mönster från ingångspunkten /native: lägg till feedbackPlugin() i samma @sonenta/react-i18next-providers plugins-plats i din Expo-app och utlös via kontrollern. Inga extra nativa moduler; token-lagringen använder plattformens secure store.

App.tsx
1// App.tsx (Expo / React Native) — same plugins slot2import { SonentaProvider } from "@sonenta/react-i18next";3import { feedbackPlugin } from "@sonenta/feedback/native"; 5<SonentaProvider6  projectUuid="proj_xxx"7  token={process.env.EXPO_PUBLIC_SONENTA_TOKEN}8  plugins={[ feedbackPlugin({ onReady: (c) => (ctrl = c) }) ]}9>{/* … */}</SonentaProvider> 11// wire ctrl.open() to your own button / FAB

4. Vue

@sonenta/feedback/vue är en fristående adapter — explicit konfiguration, ingen i18n-provider att ärva från. createFeedback(config) returnerar { client, isOpen, controller, FeedbackPanel }. Montera <FeedbackPanel /> en gång nära din rot (den Teleporterar till body), och anropa controller.open() från din egen CTA. Samma isolerade öppna-tillstånd — det omrenderar aldrig din app.

App.vue
1// main.ts — standalone adapter, explicit config2import { createFeedback } from "@sonenta/feedback/vue"; 4export const { controller, FeedbackPanel } = createFeedback({5  apiBase: "https://api.sonenta.com",6  projectId: "proj_xxx", language: "fr",7}); 9// App.vue — mount once near root (Teleports to body)10<FeedbackPanel />11<button @click="controller.open()">Rate translations</button>

5. Svelte

@sonenta/feedback/svelte är headless och idiomatisk: createFeedback(config) returnerar Svelte-stores — isOpen (Writable), strings (Writable) — plus open(), close(), loadStrings(), rate(), suggest(). Du renderar din egen panel från storesen; SDK:t äger transporten, samtycket och serversessionen.

+page.svelte
1// feedback.ts — headless idiomatic stores2import { createFeedback } from "@sonenta/feedback/svelte"; 4export const fb = createFeedback({5  apiBase: "https://api.sonenta.com",6  projectId: "proj_xxx", language: "fr",7}); 9// component — render your own panel from the stores10{#if $fb.isOpen}{#each $fb.strings as s}…{/each}{/if}11<button on:click={fb.open}>Rate translations</button>

6. Allt annat — /core

@sonenta/feedback/core exponerar den frysta FeedbackClient som alla adaptrar bygger på: acceptTos(), loadStrings(), rate(), suggest(), debouncad batchad transport, roterande JWT. Använd den direkt för vilket ramverk som helst utan en förstapartsadapter.

feedback.ts
1// any framework — the frozen client all adapters wrap2import { FeedbackClient } from "@sonenta/feedback/core"; 4const client = new FeedbackClient({5  apiBase: "https://api.sonenta.com",6  projectId: "proj_xxx", language: "fr",7});8await client.acceptTos();   // server mints the session9await client.loadStrings(); client.rate(/* … */); client.suggest(/* … */);

7. Avgränsning till renderade nycklar (automatisk)

Panelen avgränsas automatiskt till de nycklar som faktiskt renderas i den aktuella vyn, via det globala nyckelregister som @sonenta/*-i18n-SDK:t producerar — ingen konfiguration. Skicka en explicit keys-array endast som en fallback (t.ex. strängar som inte kommer från @sonenta/*-i18n); skicka aldrig hela din katalog — det skulle exponera varje sträng i appen, inte de som användaren tittar på. Registret är monteringsspårat och referensräknat: beständiga strängar som alltid är på skärmen (en sidhuvud, en eyebrow) förblir registrerade så länge deras komponent är monterad — det finns ingen återställning per vy. (reset() finns endast som en nödutgång för kantfall med icke-React-routing; SDK:t anropar den aldrig automatiskt.)

scoping.ts
1// the panel auto-scopes to keys RENDERED on the current2// view, via the global key registry the @sonenta/*-i18n3// SDK produces — no config needed:4feedbackPlugin({ controllerRef: feedback });   // auto-scoped 6// explicit keys = FALLBACK only (e.g. strings not from7// @sonenta/*-i18n). NEVER pass your whole catalogue.8feedbackPlugin({ keys: ["common:checkout.cta"] });

8. Namespace-filter (valfritt)

En skärm som renderar flera namespaces kan avgränsa panelen till just det som kunden bryr sig om — skicka ett valfritt namespace (string | string[]) på triggern/konfigurationen (feedbackPlugin() för React/Native, createFeedback() för Vue/Svelte, resolveKeys() / filterByNamespace() för /core). Det kombineras efter avgränsningen till renderade nycklar — visat = renderat ∩ namespace. Odefinierat, "" eller [] betyder inget filter (identiskt med tidigare). Det faller aldrig tillbaka till hela projektet.

namespace.ts
1// §0d — OPTIONAL namespace filter (customer feature).2// Composes AFTER rendered-scoping: shown = rendered ∩ namespace.3feedbackPlugin({ controllerRef: feedback, namespace: "quiz" }); 5// Vue / Svelte — same option on createFeedback:6createFeedback({ apiBase, projectId, language, namespace: ["quiz"] }); 8// /core — resolveKeys / filterByNamespace:9resolveKeys(explicit, "quiz");   // or filterByNamespace(keys, "quiz") 11// unset / "" / [] ⇒ no filter (identical to v5).

9. Serversidigt skapad session (alla ramverk)

Session-/grupperingsnyckeln skapas på serversidan vid samtycke. Klienten skickar eller genererar den aldrig själv — det finns ingen groupingKey-konfiguration och inget begäransfält. Vid acceptTos() returnerar backend den (bunden i den scopebegränsade JWT:n); varje adapter exponerar den skrivskyddat som client.sessionId. Ett återkommande endUserId behåller sitt stabila servervärde; en ny slutanvändare får ett färskt sess_….

consent.ts
1// session/grouping key is MINTED SERVER-SIDE at consent2await client.acceptTos();      // POST /v1/feedback/tos3client.sessionId;              // read-only, e.g. "sess_018f…" 5// NO groupingKey config, NO request field —6// the client never sends or self-generates the session.

10. Samtycke & säkerhet (automatiskt)

Före den första skrivningen accepterar slutanvändaren Sonentas versionshanterade slutanvändarvillkor. SDK:t skaffar sedan en kortlivad JWT som är begränsad till enbart scopet feedback:write — kryptografiskt åtskild från din kundautentisering — och roterar den transparent. Slutanvändare är anonyma (ogenomskinligt id, ingen PII). Du behöver inte koda något på säkerhetssidan.

Vad du får utan ansträngning

Härnäst