Gå til innholdet
Sonenta

SDK · Sluttbrukervurdering

Forhåndsvisning

@sonenta/feedback

La dine egne sluttbrukere vurdere (5★) og foreslå oversettelser rett fra appen du har publisert. React og React Native kobler seg på @sonenta/*-i18n-provideren du allerede kjører (ingen ekstra kontekst, ingen re-render av verten); alt annet går gjennom /core, den frosne klienten som alle bindingene pakker inn. Samme protokoll, samme serverskapte økt, samme moderasjons-backoffice. Tilgjengelig som betalt tillegg fra Pro.

Pakken @sonenta/feedback leveres med tillegget for sluttbrukervurdering av oversettelser ved Sonenta V1-lanseringen. Wire-kontrakten er frosset (v3); framework-bindingene stabiliseres fortsatt og kan endre seg 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
controllerRefRef<Controller>,
onReady(c) => void,
keysstring[]auto-discovered
flushDebounceMsnumber1500
maxBatchnumber20
defaultButtonbooleanfalse

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. 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.dev",6  projectId: "proj_xxx", language: "fr",7  // REQUIRED. Without it, the first authenticated call8  // accepts the end-user ToS on your user's behalf.9  autoAcceptTos: false,10}); 12// show YOUR ToS step, and only once the user agrees:13await client.acceptTos();   // server mints the session14await client.loadStrings(); client.rate(/* … */); client.suggest(/* … */); 16// with autoAcceptTos:false, an unconsented authed call throws17// FeedbackError("not consented") instead of fabricating a record.

5. 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"] });

6. 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).

7. 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.

8. Samtykke og sikkerhet

En versjonert Sonenta-sluttbrukeravtale ligger foran den første skrivingen. I React- og React Native-panelene vises samtykkesteget før ethvert autentisert kall, og det er sluttbrukerens eget trykk som kaller acceptTos(): henting av strengene er koblet til samtykke ved konstruksjon. Bruker du /core i stedet, opprett klienten med autoAcceptTos: false og kall acceptTos() først når brukeren din har samtykket, ellers samtykker det første autentiserte kallet på vegne av vedkommende. Klienten holder deretter et kortlevd JWT som kun er begrenset til feedback:write, kryptografisk adskilt fra din egen kundeautentisering, og roterer det transparent. Sluttbrukere er anonyme (ugjennomsiktig id, ingen personopplysninger). På @sonenta/feedback 1.2.x og eldre er dette STANDARDATFERDEN: klienten samtykker ved det første autentiserte kallet med mindre du sender autoAcceptTos: false. Versjon 1.3.0 snur standarden og feiler trygt, ved å kaste FeedbackError("not consented") i stedet for å samtykke på vegne av brukeren din.

Hva du får gratis

Videre