Lingara Lingara Dokumentasie Gidse API Biblioteke Apps Bou Inbed Webtoepassing
Taal: Afrikaans

Webwerf-widget

Hierdie bladsy is uit Engels vertaal. As die twee verskil, is die Engelse bladsy korrek. Lees die Engelse bladsy

Op ‘n webwerf loop Lingara as ‘n pasgemaakte element, <lingara-embed>. Die element teken Lingara se oefening in ‘n raam wat deur Lingara bedien word, so jou bladsy sien nooit die leerder se data nie en Lingara se bladsy sien nooit joune nie.

Monteer die element

Installeer @lingara/embed vanaf npm, of laai sy modulebou vanaf ‘n CDN as jou webwerf geen bundler het nie. Sit dan <lingara-embed> op die bladsy en definieer dit. Die element neem:

  • plan-id, die lesplan om te oefen, een wat die speler besit;
  • surface, wat om te wys: practice, die verstek en die enigste oppervlak wat daar is;
  • theme, een van light, dark of auto;
  • locale, die taal van die raam se eie woorde, wat andersins die leerder volg;
  • title, die raam se toeganklike naam.

Stilering stop by die tema. Jou bladsy kan nie binne die raam reik nie, en die tema is die enigste instelling wat dit bied.

Gee dit tokens

Stel die element se tokenProvider op ‘n funksie wat jou eie bediener vir ‘n token vra. Jou bediener reik dit met die bladsy se oorsprong uit, met ‘n bedienerkit, en antwoord met die token en sy vervaltyd. Die element gee die token per boodskap aan die raam, en dit reis nooit in ‘n URL nie.

Registreer elke oorsprong waarop die widget loop voordat jy ‘n token daarvoor uitreik, in jou kliënt se instellings in die konsole. Die bladsy Bedienerkits sê hoe. Die API weier ‘n token wat vir enige ander oorsprong uitgereik is, en die raam wys ‘n fout in plaas van oefening.

‘n Bedienerkit kan ook die hele brokkie vir jou skryf, element en tokenverskaffer saam, met jou bladsy se skrip-nonce as jou inhoudsekuriteitsbeleid een vereis. Die laaste voorbeeld hieronder wys dit.

Luister na wat die raam sê

Die raam praat met die element oor ‘n geweergaweerde boodskapprotokol, en die element maak van wat jou bladsy nodig het DOM-gebeurtenisse:

  • lingara:practice-completed wanneer die leerder ‘n stel voltooi, met sy planId, setNumber, correct en total;
  • lingara:error wanneer die raam stop, met ‘n code en retryable. ‘n Herprobeerbare fout beteken ‘n vars montering kan slaag; wanneer om weer te probeer, besluit jy.

Die resultaat van die oefening bereik ook jou bediener, soos beskryf in oefenresultate.

npm install @lingara/embed@0.1.0-alpha.6
# No bundler? One module script instead:
# <script type="module" src="https://cdn.jsdelivr.net/npm/@lingara/embed@0.1.0-alpha.6/dist/lingara-embed.min.js"></script>
<!-- plan-id is a lesson plan your server made for this player. -->
<lingara-embed surface="practice" plan-id="0b9d4f2e-3c1a-4e8b-9f6d-2a7c5e1b8d40" theme="auto" title="Practice"></lingara-embed>
<script type="module">
  import { defineLingaraEmbed } from '@lingara/embed'
  defineLingaraEmbed()
</script>
// Your own endpoint, on your own server. It mints with this page's origin and
// returns exactly { token, expires_at }: the token (lgr_et_…) never touches a URL.
widget.tokenProvider = async () => {
  const response = await fetch('/lingara/token', { method: 'POST', credentials: 'same-origin' })
  if (!response.ok) throw new Error(`token endpoint answered ${response.status}`)
  return response.json()
}
widget.addEventListener('lingara:practice-completed', (event) => {
  const { planId, setNumber, correct, total } = (event as CustomEvent).detail
  console.log(`set ${setNumber} of ${planId}: ${correct}/${total}`)
})
widget.addEventListener('lingara:error', (event) => {
  const { code, retryable } = (event as CustomEvent).detail
  // `retryable` means a remount may succeed; when to try is yours to decide.
  if (retryable) setTimeout(() => widget.reload(), 30_000)
  else console.warn('Lingara practice stopped:', code)
})
Taal van die kodevoorbeeld

TypeScript

// The page that mounts the widget: the token never appears in it.
export function practicePage(planId: string, cspNonce: string): string {
  const widget = widgetSnippet({ planId, tokenEndpoint: '/lingara/token', theme: 'auto', locale: 'fr', title: 'Pratique', nonce: cspNonce })
  return `<!doctype html><title>Practice</title>${widget}`
}

Rust

// The element, its script build and a token provider that POSTs to your
// token route. The token never appears in the markup.
let html = widget_snippet(&SnippetOptions {
    locale: Some("fr".into()),
    nonce: Some(csp_nonce.into()), // your page's CSP nonce, for a strict script-src
    ..SnippetOptions::new(plan_id, "/lingara/token")
})?;

Go

// The plan your server made for this player, and the token route above.
// Pass the request's CSP nonce when your script-src allows no inline
// script; the token itself never appears in the markup.
theme := "auto"
html, err := lingaraembed.WidgetSnippet(lingaraembed.SnippetOptions{
	PlanID:        planID,
	TokenEndpoint: "/lingara/token",
	Theme:         &theme,
	Nonce:         &cspNonce,
})
if err != nil {
	return "", err // a *lingaraembed.SnippetError names the refused option
}
return template.HTML(html), nil // already escaped by the kit

Java

// planId is the lesson plan your server made for this player. The element
// POSTs to tokenEndpoint with same-origin cookies: the token never appears
// in the markup. Pass this request's CSP nonce if your page sets one.
String html =
    WidgetSnippet.render(
        SnippetOptions.builder(planId, "/lingara/token").locale("fr").nonce(cspNonce).build());

Kotlin

// planId is the lesson plan your server made for this player. The element
// POSTs to tokenEndpoint with same-origin cookies: the token never appears
// in the markup. Pass this request's CSP nonce if your page sets one.
val html =
    widgetSnippet(
        SnippetOptions(planId, tokenEndpoint = "/lingara/token").apply {
            locale = "fr"
            nonce = cspNonce
        },
    )

Ruby

# The plan your server made for this player, rendered into your page.
# nonce: your page's CSP nonce, when its script-src allows no inline script.
def self.widget(plan_id, csp_nonce)
  Lingara::Embed.widget_snippet(plan_id: plan_id, token_endpoint: "/lingara/token", locale: "fr", nonce: csp_nonce)
end

PHP

use Lingara\Embed\SnippetOptions;
use Lingara\Embed\WidgetSnippet;

// In your page's template: the plan your server made for this player, and
// your token route. Pass the request's CSP nonce if your script-src allows
// no inline script. A bad option throws SnippetException naming its field.
function practiceWidget(string $planId, string $cspNonce): string
{
    return WidgetSnippet::render(new SnippetOptions(
        planId: $planId,
        tokenEndpoint: '/lingara/token',
        theme: 'auto',
        nonce: $cspNonce,
    ));
}

C#

app.MapGet("/practice/{planId}", (string planId, HttpContext http) =>
{
    var widget = WidgetSnippet.Render(new SnippetOptions
    {
        PlanId = planId,                              // the plan your server made for this player
        TokenEndpoint = "/lingara/token",             // same origin: the element sends this page's cookies
        Nonce = http.Items["csp-nonce"] as string,     // your CSP's nonce, if script-src has one
    });
    return Results.Content($"<!doctype html><title>Practice</title>\n{widget}", "text/html");
}).RequireAuthorization();