SDK · Sluttbrukervurdering
Forhåndsvisning@sonenta/feedback
La dine egne sluttbrukere vurdere (5★) og foreslå oversettelser fra appen din i produksjon. Én pakke, fem inngangspunkter — /react, /native, /vue, /svelte, /core — samme wire, samme serversignerte økt, samme moderasjons-backoffice. React og React Native kobler seg på @sonenta/*-i18n-provideren du allerede bruker (ingen ekstra kontekst, ingen re-render av verten); Vue og Svelte er idiomatiske, frittstående adaptere. Tilgjengelig som et betalt tillegg fra og med Pro.
Pakken @sonenta/feedback leveres med tillegget «Sluttbrukervurdering av oversettelser» ved Sonentas V1-lansering. Den er ikke på npm ennå — wire-kontrakten er fryst (v3); framework-bindingene stabiliseres og kan fortsatt endres før lansering.
1. Installer (ved lansering)
Én enkelt pakke. Importer inngangspunktet for ditt framework: @sonenta/feedback/react, /native (RN/Expo), /vue, /svelte, eller /core for resten. vue / svelte er valgfrie peer deps — bare det aktuelle inngangspunktet trenger dem. Publiseres med tillegget ved 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 (web) — i18n-plugin
Legg til feedbackPlugin() i plugins-sloten til din eksisterende @sonenta/react-i18next-provider (>= 0.7.0) — ingen ny provider, ingen ekstra kontekst. Provideren kaller pluginens setup() én gang og gjenbruker sine egne apiBase / projectId / defaultLocale. Panelet monteres som et isolert søskenblad med en privat åpne/lukke-store, så å åpne det re-rendrer aldri verts-treet ditt. Utløs fra din egen CTA via kontrolleren som leveres gjennom 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> Alle alternativer for feedbackPlugin() / createFeedback()
| Alternativ | Type | Standard |
|---|---|---|
| controllerRef | Ref<Controller> | — |
| onReady | (c) => void | — |
| keys | string[] | auto-discovered |
| flushDebounceMs | number | 1500 |
| maxBatch | number | 20 |
| defaultButton | boolean | false |
3. React Native / Expo
Samme mønster fra inngangspunktet /native: legg til feedbackPlugin() i plugins-sloten til den samme @sonenta/react-i18next-provideren i Expo-appen din og utløs via kontrolleren. Ingen ekstra native moduler; token-lagring bruker 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 er en frittstående adapter — eksplisitt config, ingen i18n-provider å arve fra. createFeedback(config) returnerer { client, isOpen, controller, FeedbackPanel }. Monter <FeedbackPanel /> én gang nær roten (Teleporter til body), og kall controller.open() fra din egen CTA. Samme isolerte åpne-tilstand — den re-rendrer aldri appen din.
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 er headless og idiomatisk: createFeedback(config) returnerer Svelte-stores — isOpen (Writable), strings (Writable) — pluss open(), close(), loadStrings(), rate(), suggest(). Du rendrer ditt eget panel fra storene; SDK-en håndterer transport, samtykke og serverøkten.
+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. Resten — /core
@sonenta/feedback/core eksponerer den fryste FeedbackClient som alle adaptere er bygd på: acceptTos(), loadStrings(), rate(), suggest(), debounced og batchet transport, roterende JWT. Bruk den direkte for ethvert framework uten en førsteparts-adapter.
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. Avgrensing til viste nøkler (automatisk)
Panelet avgrenses automatisk til nøklene som faktisk er vist i gjeldende visning, via det globale nøkkelregisteret som @sonenta/*-i18n-SDK-en produserer — ingen konfigurasjon. Send et eksplisitt keys-array kun som en fallback (f.eks. strenger som ikke kommer fra @sonenta/*-i18n); send aldri hele katalogen din — det ville eksponert alle strengene i appen, ikke de brukeren ser på. Registeret er monteringssporet og referansetelt: vedvarende strenger som alltid er på skjermen (en header, en eyebrow) forblir registrert så lenge komponenten deres er montert — ingen tilbakestilling per visning. (reset() finnes kun som en nødutgang for kantsaker med ikke-React-ruting; SDK-en kaller den aldri automatisk.)
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 (valgfritt)
En skjerm som rendrer flere namespaces kan avgrense panelet til nettopp det kunden bryr seg om — send et valgfritt namespace (string | string[]) på trigger/config (feedbackPlugin() for React/Native, createFeedback() for Vue/Svelte, resolveKeys() / filterByNamespace() for /core). Det settes sammen etter avgrensningen til viste nøkler — vist = vist ∩ namespace. Udefinert, "" eller [] betyr ingen filter (identisk med før). Det faller aldri tilbake til hele prosjektet.
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. Serversignert økt (alle frameworks)
Økt-/grupperingsnøkkelen signeres på serversiden ved samtykke. Klienten sender eller genererer den aldri selv — det finnes ingen groupingKey-config og ingen forespørselsfelt. Ved acceptTos() returnerer backend den (bundet inn i det scope-begrensede JWT-et); hver adapter eksponerer den skrivebeskyttet som client.sessionId. En returnerende endUserId beholder sin stabile serververdi; en ny sluttbruker får en fersk 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. Samtykke og sikkerhet (automatisk)
Før den første skrivingen godtar sluttbrukeren de versjonerte sluttbrukervilkårene til Sonenta. SDK-en henter deretter et kortlevd JWT begrenset til feedback:write-scope alene — kryptografisk adskilt fra din kunde-auth — og roterer det transparent. Sluttbrukere er anonyme (ugjennomsiktig id, ingen PII). Du trenger ikke kode noe på sikkerhetssiden.
Hva du får gratis
- Null re-render av verten. React/Native kjører som et isolert søskenblad av i18n-provideren; Vue/Svelte holder åpne-tilstand i sin egen store. Å legge til eller åpne feedback re-rendrer aldri appen din.
- Samtykke + serverøkt håndtert. Godkjenning av vilkår, serversignert økt, JWT-henting, roterende refresh og ett transparent retry-forsøk ved 401 — alt inne i SDK-en. Den kaster aldri unntak inn i render-banen din.
- Debounced, batchet transport. Vurderinger og forslag køes og tømmes på en debounce (standard 1,5 s), ved en maks-batch, eller ved lukking. Best-effort: en mislykket batch køes på nytt én gang, deretter svelges den.
- Moderasjon før publisering. Ingenting en sluttbruker sender inn går live automatisk. Forslag lander som
pendingi moderasjonskøen i dashbordet ditt — du godkjenner, avviser eller anvender via den normale, reviderte redigeringsbanen. Vurderinger aggregeres i et sanntidsdashbord per nøkkel / per språk.