Integrationen

Sanity (TMS)

Inhalte werden von Phrase Language AI maschinell aus dem Englischen übersetzt.

Das Plug-in bietet Zugriff auf die von Phrase übersetzten Inhalte innerhalb des Sanity Studios.

Es werden nur Übersetzungen auf Dokumentenebene unterstützt. Übersetzungen auf Feldebene werden nicht unterstützt.

Funktionen:

  • Echtzeit-Vorschauen

    Übersetzungen werden synchron gehalten, damit Linguisten und Übersetzer Vorschauänderungen in Echtzeit sehen können.

  • Intelligente Neuübersetzungen

    Das Plug-in vergleicht, welche Inhalte sich seit der letzten Übersetzung geändert haben, und sendet nur diese Änderungen an Phrase.

  • Automatische Referenzübersetzung

    Bei der Ausgabe von Übersetzungen können Redakteure auch wählen, Dokumente zu übersetzen, die von der aktuellen Übersetzung referenziert werden, und das Plug-in verknüpft sie automatisch nach Zielsprache.

  • Flexible Schemata

    Unabhängig von der Struktur passt sich das Plug-in daran an und stellt sicher, dass der endgültige übersetzte Inhalt den Sanity-Schemata entspricht.

  • Phrase-Workflows

    Die Übersetzungs-Workflows in Phrase bleiben gleich; eine Schulung oder Neukonfiguration der Abläufe ist nicht erforderlich.

Sanity Plugin Installation

Die Installation erfolgt über die Kommandozeile.

Es wird davon ausgegangen, dass ein Website-Generator und Sanity Studio bereits konfiguriert sind. Falls nicht, verwenden Sie eine der von Sanity bereitgestellten Starter-Vorlagen.

Installation

Navigieren Sie zu dem Projekt, das die Sanity Studio-Instanz enthält, und installieren Sie das Plug-in:

npm install sanity-plugin-phrase

# oder pnpm, yarn, bun

Umgebungsvariablen

Bevor das Plug-in konfiguriert wird, müssen die folgenden Umgebungsvariablen festgelegt werden. Erstellen Sie eine `.env`-Datei (oder `.env.local` für Next.js) im Projektstamm.

Die folgenden Beispiele gelten für NextJS. Für andere Frameworks konsultieren Sie deren spezifische Dokumentation und beachten Sie, dass das Präfix `NEXT_PUBLIC_` möglicherweise für öffentliche Variablen entfernt werden muss.

Wichtig

Serverseitige Variablen (SANITY_WRITE_TOKEN, PHRASE_USER_NAME, PHRASE_PASSWORD) sollten niemals dem Kunden ausgesetzt werden. In Next.js sind nur Variablen, die mit NEXT_PUBLIC_ beginnen, im Browser sichtbar.

# Basis-URL Ihrer Website (verwendet für Vorschau-Links)
NEXT_PUBLIC_BASE_URL="http://localhost:3000"

# URL, an der der Backend-Handler des Plug-ins zu finden sein wird
NEXT_PUBLIC_PHRASE_PLUGIN_API_ENDPOINT="http://localhost:3000/api/phrase"

# Phrase-Datacenter-Region ('eu' oder 'us')
NEXT_PUBLIC_PHRASE_REGION="eu"

# Sanity-Projektkonfiguration
NEXT_PUBLIC_SANITY_PROJECT_ID="your-project-id"
NEXT_PUBLIC_SANITY_DATASET="production"

# Sanity API-Token mit Schreibberechtigungen (nur serverseitig)
SANITY_WRITE_TOKEN=""

# Phrase-Anmeldeinformationen (nur serverseitig)
# Hinweis: Die Phrase API erwartet nur den Benutzernamen, NICHT die vollständige E-Mail-Adresse
PHRASE_USER_NAME="phraseUsername"
PHRASE_PASSWORD="secretPassword"

Plug-in-Konfiguration

Das Plug-in wird zu sanity.config.ts mit den erforderlichen Konfigurationsoptionen hinzugefügt:

// sanity.config.ts
import { defineConfig } from 'sanity'
import {
  phrasePlugin,
  definePhraseOptions,
  documentInternationalizationAdapter,
} from 'sanity-plugin-phrase'

const PHRASE_CONFIG = definePhraseOptions({
  // Erforderlich: i18n-Adapter für die Internationalisierung von Dokumenten
  i18nAdapter: documentInternationalizationAdapter(),

  // Erforderlich: Dokumenttypen, die übersetzt werden können
  translatableTypes: ['page', 'post', 'article'],

  // Erforderlich: Ausgangssprache (Primärsprache)
  // Dies muss mit der Sprache übereinstimmen, die in Ihrer Phrase-Projektvorlage definiert ist
  sourceLang: 'en',

  // Erforderlich: Zielsprache, in die Benutzer übersetzen können
  // Verwenden Sie dieselben Codes wie Ihre Sanity-Dokumente
  // Diese Liste muss mit den in Ihrer Phrase-Projektvorlage definierten Sprachen übereinstimmen
  supportedTargetLangs: ['es', 'fr', 'de', 'pt'],

  // Erforderlich: Ihre Backend-API-Endpunkt-URL
  apiEndpunkt: process.env.NEXT_PUBLIC_PHRASE_PLUGIN_API_ENDPOINT!

  // Erforderlich: Phrase-Datacenter-Region ('eu' oder 'us')
  phraseRegion: process.env.NEXT_PUBLIC_PHRASE_REGION as 'eu' | 'us',

  // Erforderlich: Phrase-Projektvorlagen, die den Redakteuren zur Verfügung stehen
  phraseTemplates: [
    {
      vorlagenUid: 'YOUR_TEMPLATE_UID_HERE',
      label: 'Standardübersetzungs-Vorlage',
    },
  ],

  // Erforderlich: Vorschau-URLs für Linguisten generieren
  getDocumentPreview: (doc, sanityClient) => {
    const publishedId = doc._id.Ersetzen('drafts.', '')
    return `${process.env.NEXT_PUBLIC_BASE_URL}/api/draft?id=${publishedId}`
  },

  // Optionale Einstellungen

  // Maximale Tiefe für die Übersetzung referenzierter Dokumente (Standard: 3)
  maxReferencesDepth: 3,

  // Übersetzung von Entwurfsdokumenten erlauben (Standard: false)
  translateDrafts: false,

  // Benutzerdefinierte Daten-Transformatoren für spezielle Inhaltstypen
  dataTransformers: [],

  // Protokollierungs-Konfiguration für Debugging
  logger: {
    minimumLogLevel: 'info', // 'debug' | 'info' | 'warning' | 'error' | 'fatal'
  },

  // Phrase-Dashboard basierend auf Benutzerrollen ausblenden
  isPhraseDashboardHidden: (context) =>
    !(context.currentUser.roles || []).some((r) => r.name === 'admin'),
})

export default defineConfig({
  // ... Ihre bestehende Konfiguration
  plugins: [
    phrasePlugin(PHRASE_CONFIG),
    // ... andere Plugins
  ],
})// sanity.config.(js|ts)
import {
  phrasePlugin,
  documentInternationalizationAdapter,
} from 'sanity-plugin-phrase'

const PHRASE_CONFIG = definePhraseOptions({
  /**
   * Der i18n-Adapter, der für dieses Plug-in verwendet werden soll.
   * Er wird dafür verantwortlich sein, Dokumente für jede Zielsprache abzurufen und zu ändern.
   *
   * Siehe unten für weitere Informationen zu Adaptern.
   */
  i18nAdapter: documentInternationalizationAdapter(),

  /**
   * Sanity-Schema-Typen, die das Plug-in übersetzen kann
   */
  translatableTypes: ['page', 'post', 'course', 'lesson', 'definition'],

  /**
   * Sprachcode aller Sprachen, in die Benutzer übersetzen können.
   * Sollte derselbe sein wie der, der in Ihren Sanity-Dokumenten gespeichert ist und von Ihrem Front-End verwendet wird. Das Plug-in wird es automatisch in das Format von Phrase übersetzen.
   */
  supportedTargetLangs: ['cz', 'es', 'pt', 'fr', 'de', 'it', 'nl', 'pl', 'ru'],

  /**
   * Sprachcode der Ausgangssprache, die übersetzt werden soll.
   * Sollte derselbe sein wie der, der in Ihren Sanity-Dokumenten gespeichert ist und von Ihrem Front-End verwendet wird. Das Plug-in wird es automatisch in das Format von Phrase übersetzen.
   */
  sourceLang: 'en',

  /**
   * Wie in den Einstellungen Ihres Phrase-Kontos definiert
   * Entweder `eu` oder `us`
   */
  phraseRegion: 'us|eu',

  /**
   * Die URL zu Ihrer konfigurierten Plug-in-Backend-API.
   *
   * **Hinweis:** Befolgen Sie die Schritte zur Einrichtung des Endpunkts, die unten aufgeführt sind
   */
  apiEndpoint: 'https://my-site.com/api/phrase',

  /**
   * Wird verwendet, um Linguisten vom Phrase-Dashboard zur Front-End-Vorschau ihrer Übersetzungen umzuleiten.
   */
  getDocumentPreview: async (doc, sanityClient) => {
    const publishedId = doc._id.Ersetzen('drafts.', '')
    return `${process.env.NEXT_PUBLIC_FRONT_END_URL}/api/draft?publishedId=${publishedId}`
  },

  /**
   * Phrase-Projektvorlagen, die Ihre Redakteure bei der Anforderung von Übersetzungen verwenden können.
   *
   * **Hinweis:** Befolgen Sie die Schritte zur Einrichtung von Vorlagen, die unten aufgeführt sind
   */
  phraseTemplates: [
    {
      templateUid: '1jYg0Pc1d8kAHUyM0tgdmt',
      Label: '[Sanity.io] Standardvorlage',
    },
  ],

  /**
   * @optional
   * Falls Sie das Phrase-Dashboard je nach Benutzerrechten anzeigen oder ausblenden möchten.
   *
   * Erhält einen Kontext mit dem aktuellen Benutzer und Dokument und muss einen booleschen Wert zurückgeben.
   */
  isPhraseDashboardHidden: (context) =>
    !(context.currentUser.roles || []).some((r) => r.name === 'admin'),
})

export default defineConfig({
  // ...
  plugins: [
    // ...
    phrasePlugin(PHRASE_CONFIG),
  ],
})

Sanity Plug-in-Konfiguration

Schema-Injektion

Um dem Plug-in mitzuteilen, welche Dokumenttypen übersetzt werden können, übergeben Sie ein Array von Dokumenttypen an die injectPhraseIntoSchema-Funktion in der sanity.config.ts-Datei:

// sanity.config.ts
import { injectPhraseIntoSchema } from 'sanity-plugin-phrase'

// Liste der übersetzbaren Schema-Typen. Normalerweise aus einer Indexdatei exportiert
// wo auch immer sich Ihr Sanity-Schema befindet
const TRANSLATABLE_SCHEMAS = ['Seite', 'Beitrag', 'Kurs', 'Lektion', 'Definition']

export default defineConfig({
  schema: {
    types: injectPhraseIntoSchema(TRANSLATABLE_SCHEMAS, PHRASE_CONFIG),
    templates: (prev) =>
      prev.filter((template) => !TRANSLATABLE_SCHEMAS.includes(template.id))
  },
  plugins: [
    // ...
    phrasePlugin({
      // Ihre Konfigurationsoptionen hier
    }),
  ],
})

Ausschluss von PTDs aus Dokumentlisten

PTDs (Phrase-Übersetzungsdokumente) sind temporäre Dokumente, die nicht in normalen Dokumentlisten innerhalb von Sanity Studio erscheinen sollten. Die NOT_PTD-Konstante bietet einen GROQ-Filter für diesen Zweck:

// sanity.config.ts
importieren { NOT_PTD } von 'sanity-plugin-phrase/utils'

export default defineConfig({
  // ... andere Konfiguration
  plugins: [
    structureTool({
      struktur: (S) =>
        S.list()
          .title('Content')
          .items([
            S.listItem()
              .title('Posts')
              .schemaType('post')
              .child(
                S.documentList()
                  .title('Posts')
                  .filter(`_type == "post" && ${NOT_PTD}`),
              ),
            // ... andere Elemente
          ]),
    }),
  ],
})

Das Übersetzungsmenü von PTDs ausblenden

Beim Verwenden des Dokument-Internationalisierungs-Plug-ins sollte das Übersetzungsmenü von PTDs ausgeblendet werden. Die isPtdId Utility identifiziert PTD-Dokumente:

import { isPtdId } from 'sanity-plugin-phrase/utils'
importieren { DocumentInternationalizationMenu } von '@sanity/document-internationalization'

// Verwenden Sie dasselbe Array wie translatableTypes aus Ihrer PHRASE_CONFIG
const TRANSLATABLE_TYPES = ['Seite', 'Beitrag', 'Artikel']

export default defineConfig({
  Dokument: {
    unstable_languageFilter: (prev, ctx) => {
      const { schemaType, documentId } = ctx

      // Zeigen Sie das Übersetzungsmenü nur für echte Dokumente an, nicht für PTDs
      return TRANSLATABLE_TYPES.includes(schemaType) &&
        documentId &&
        !isPtdId(documentId)
        ? [...prev, DocumentInternationalizationMenu]
        : prev
    },
  },
})

Phrase-Konfiguration

Das Plug-in hat keine Konfiguration in der Phrase-Benutzeroberfläche, aber Phrase muss konfiguriert werden, um Webhook-Benachrichtigungen an den Backend-API-Endpunkt zu senden. Dies ermöglicht Echtzeit-Updates, während die Übersetzungen fortschreiten.

Erstellen Sie einen Webhook

Erstellen Sie einen Webhook mit diesen Einstellungen:

  • URL

    Die URL zum API-Endpunkt des Plug-ins, wie im apiEndpoint Option konfiguriert.

  • Veranstaltungen:

    • Jobs

      • Job gelöscht

      • Job zugewiesen

      • Fälligkeitsdatum des Jobs geändert

      • Job-Ziel aktualisiert

    • Projekte

      • Projekt gelöscht

      • Fälligkeitsdatum des Projekts geändert

    • Andere

      • Vorübersetzung abgeschlossen

Dies stellt sicher, dass das Plug-in über Änderungen an Phrase-Projekten informiert wird und die Sanity-Daten synchron halten kann.

Projekte-Vorlage(n) einrichten

Konfigurieren Sie die Phrase Projektvorlage(n) mit den für Workflows und Teamanforderungen erforderlichen Eigenschaften. Eines oder mehrere Vorlagen können angeboten werden, aus denen bei der Bestellung einer neuen Übersetzung gewählt werden kann. Die Projektvorlagen für Phrasen müssen spezifische JSON-Importeinstellungen haben, damit das Plug-in korrekt funktioniert. Diese Einstellungen steuern, welche Felder an Übersetzer gesendet werden und welche als Metadaten erhalten bleiben.

JSON-Datei-Import

Verwenden Sie Regex, um bestimmte Keys auszuschließen:

(^|.*\/)
(_createdAt|_id|_rev|_type|_updatedAt|_ref|_key|_sanityRev|_sanityContext|_strengthenOnPublish|phraseMetadata|_spanMeta|_blockMeta|_diff|marks|IHRE_IGNORIERTEN_KEYS_HIER|
(_createdAt|_id|_rev|_type|_updatedAt|_ref|_key|_sanityRev|_sanityContext|_strengthenOnPublish|phraseMetadata|_spanMeta|_blockMeta|_diff|marks|IHRE_IGNORIERTEN_KEYS_HIER)
/.*)

Dieser Ausdruck enthält absichtlich duplizierte Keys, um sicherzustellen, dass sie vom RegEx-Parser von Phrase ignoriert werden. Stellen Sie sicher, dass sie korrekt dupliziert sind.

  • Schließen Sie lokalisierungsspezifische Daten aus, wie die Sprache eines bestimmten Dokuments, wenn Sie @sanity/document-internationalization verwenden.

  • Fügen Sie alle projektspezifischen Keys hinzu, die keine Übersetzung erfordern, wie einen Slug für Inhalte, die denselben Pfad in allen Sprachen verwenden. Ersetzen Sie IHRE_IGNORIERTEN_KEYS_HIER durch eine durch Pipes getrennte Liste von Keys, die ignoriert werden sollen.

  • Context note: /_sanityContext

Ausgangssprache

Derzeit geht dieses Plug-in davon aus, dass es eine einzige Ausgangssprache gibt. Die Projektvorlage(n) müssen die gleiche Quelle wie die im Plug-in konfigurierte sourceLanguage haben.

Zielsprache(n)

Stellen Sie sicher, dass die in Phrase gewählten Sprachen mit denen in der Konfiguration des Plug-ins synchronisiert sind.

Sanity apiEndpoint

Dies ist der Endpunkt, den das Plug-in verwendet, um mit dem Sanity Studio zu kommunizieren. Es wird verwendet, um sich bei der API von Phrase zu authentifizieren, Webhooks zu empfangen und Benutzeranfragen aus dem Sanity Studio zu erhalten.

Erstellen Sie einen individuellen API-Endpunkt im Sanity-Projekt, um diese Anfragen zu bearbeiten. Eine der einfachsten Möglichkeiten, dies zu tun, besteht darin, serverlose Funktionen über Front-End-Frameworks wie NextJS, Remix, SvelteKit oder Nuxt zu verwenden.

Zugreifen Sie auf die Konfiguration des Handlers mit einem Request-Response-Muster über import {createRequestHandler} von sanity-plugin-phrase/backend oder verwenden Sie den internen Handler direkt über import {createInternalHandler} von sanity-plugin-phrase/backend. Stellen Sie sicher, dass CORS-Anfragen korrekt behandelt werden, da das Studio und der Endpunkt unterschiedliche Ursprünge haben.

Das App-Verzeichnis von NextJS wird derzeit nicht unterstützt, da es den Backend-Handler fälschlicherweise als React-Client-Komponente analysiert.

Dieses Beispiel demonstriert die Erstellung eines Routenhandlers am konfigurierten apiEndpoint Pfad bei /api/phrase unter Verwendung des Next.js Pages Routers:

// app/api/phrase/route.ts
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } von 'next'
import { PHRASE_CONFIG } von 'phraseConfig'
import { createInternalHandler } from 'sanity-plugin-phrase/backend'

import { writeToken } von '~/lib/sanity.api'
import { client } von '~/lib/sanity.client'

export const maxDuration = 60
export const dynamic = 'force-dynamic'

const phraseHandler = createInternalHandler({
  phraseCredentials: {
    userName: process.env.PHRASE_USER_NAME || '',
    password: process.env.PHRASE_PASSWORD || '',
  },
  sanityClient: client.withConfig({ token: writeToken }),
  pluginOptions: PHRASE_CONFIG,
})

exportiere standardmäßig asynchron die Funktion handler(
  req: NextApiRequest,
  res: NextApiResponse,
) {
  res.setHeader('Access-Control-Allow-Origin', '*')
  res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS')
  res.setHeader('Access-Control-Allow-Headers', '*')

  if (req.method?.toUpperCase() === 'OPTIONS') {
    res.status(200).json({})
    return
  }

  if (
    !req.method ||
    (req.method.toUpperCase() !== 'POST' && req.method.toUpperCase() !== 'GET')
  ) {
    res.status(405).json({ error: 'Method not allowed' })
    return
  }

  const phraseRes = await phraseHandler(
    req.method.toUpperCase() === 'POST' ? req.body : req.query,
  )
  const resBody = await phraseRes.json().catch(() => {})

  Array.from(phraseRes.headers.entries()).forEach((value: [string, any]) => {
    res.setHeader(value[0], value[1])
  })
  res.status(phraseRes.status).json(resBody)
}// src/pages/api/phrase.ts
// Next.js API route: https://nextjs.org/docs/pages/building-your-application/routing/api-routes
import type { NextApiRequest, NextApiResponse } von 'next'
import { PHRASE_CONFIG } von 'phraseConfig'
import { createInternalHandler } from 'sanity-plugin-phrase/backend'
import { writeToken } von '~/lib/sanity.api'
import { client } von '~/lib/sanity.client'

const phraseHandler = createInternalHandler({
  phraseCredentials: {
    userName: process.env.PHRASE_USER_NAME || '',
    password: process.env.PHRASE_PASSWORD || '',
  },
  sanityClient: client.withConfig({ token: writeToken }),
  pluginOptions: PHRASE_CONFIG,
})

exportiere standardmäßig asynchron die Funktion handler(
  req: NextApiRequest,
  res: NextApiResponse,
) {
  res.setHeader('Access-Control-Allow-Origin', '*')
  res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS')
  res.setHeader('Access-Control-Allow-Headers', '*')

  if (req.method?.toUpperCase() === 'OPTIONS') {
    res.status(200).json({})
    return
  }

  if (
    !req.method ||
    (req.method.toUpperCase() !== 'POST' && req.method.toUpperCase() !== 'GET')
  ) {
    res.status(405).json({ error: 'Method not allowed' })
    return
  }

  const phraseRes = await phraseHandler(
    req.method.toUpperCase() === 'POST' ? req.body : req.query,
  )
  const resBody = await phraseRes.json().catch(() => {})

  Array.from(phraseRes.headers.entries()).forEach((value) => {
    res.setHeader(value[0], value[1])
  })
  res.status(phraseRes.status).json(resBody)
}

i18n-Adapter

Sanity hat keinen vorschreibenden Ansatz zur Internationalisierung, und es gibt viele Möglichkeiten, dies umzusetzen. Dieses Plug-in verwendet ein Adaptermuster, um eine Konfiguration basierend darauf zu ermöglichen, wie der Inhalt strukturiert ist und wie er übersetzt werden soll.

Derzeit ist der einzige verfügbare Adapter documentInternationalizationAdapter, der von Sanitys offiziellem document-internationalization plugin (Version ^2.0.0) verwendet wird. Reichen Sie ein Problem ein, wenn ein spezifischer Adapter erforderlich ist, oder verweisen Sie auf dieses repository's package/src/adapters/document-internationalization.ts für ein Beispiel, wie man einen angepassten implementiert.

Benutzerdefinierte Daten-Transformatoren

Wenn es erforderlich ist, Daten vor dem Senden an Phrase zu transformieren, verwenden Sie die dataTransformers Option. Dies ist nützlich, wenn die Struktur der Daten geändert werden muss oder wenn bestimmte Felder von der Übersetzung ausgeschlossen werden sollen.

Jeder Daten-Transformator muss die Daten vor dem Senden an Phrase kodieren und sie beim Empfang zurück dekodieren, um sie vor dem Speichern in Sanity zu transformieren. Mehrere Transformatoren können gestapelt und nacheinander ausgeführt werden.

Das Plug-in bietet keine Möglichkeit, Transformatoren isoliert zu testen, sodass die Entwicklung komplex sein kann. Speichern Sie echte Ziel-Dokumente aus dem Sanity-Datensatz in .JSON und verwenden Sie sie als Testdaten für jede der Funktionen kodieren/dekodieren.

Beispiel für die Modifizierung von JSON-kodierten VTT-Dateien zu HTML, damit Phrase den Inhalt der Untertitel besser segmentieren kann:

import { DataTransformer } from 'sanity-plugin-phrase'

const vttJsonTransformer: DataTransformer = {
  encode: {
    array(arr) {
      // Überprüfen, ob das Array VTT-Untertitelknoten enthält
      if (
        arr.every(
          (item) =>
            typeof item === 'object' &&
            !!item &&
            '_type' in item &&
            typeof item._type === 'string' &&
            item._type.startsWith('vtt.'),
        )
      ) {
        return encodeSubtitles(arr as StoredSubtitleNode[])
      }
      return undefined // Gibt undefined zurück, um die Transformation zu überspringen
    },
  },
  decode: {
    object(obj) {
      if (!!obj && '_type' in obj && obj._type === 'encodedSubtitles') {
        return decodeSubtitles(obj as EncodedSubtitles)
      }
      return undefined
    },
  },
}

export const PHRASE_CONFIG = definePhraseOptions({
  // ...
  dataTransformers: [vttJsonTransformer],
})export const PHRASE_CONFIG = definePhraseOptions({
  // ...
  dataTransformers: [vttJsonTransformer],
})

const vttJsonTransformer: DataTransformer = {
  encode: {
    array(arr) {
      if (
        arr.every(
          (item) =>
            typeof item === 'object' &&
            !!item &&
            '_type' in item &&
            typeof item._type === 'string' &&
            item._type.startsWith('vtt.'),
        )
      ) {
        return encodeSubtitles(arr as StoredSubtitleNode[])
      }

      return undefined
    },
  },
  decode: {
    object(obj) {
      if (!!obj && '_type' in obj && obj._type === 'encodedSubtitles') {
        return decodeSubtitles(obj as EncodedSubtitles)
      }

      return undefined
    },
  },
}

// Implementierung wird übersprungen
// Siehe /demo-nextjs/src/utils/vttJsonTransformer.ts für den vollständigen Quellcode
declare function decodeSubtitles(
  encoded: EncodedSubtitles,
): StoredSubtitleNode[]
declare function encodeSubtitles(nodes: StoredSubtitleNode[]): EncodedSubtitles

Einschränkung des Zugriffs für den Editor

Welche Editoren auf das Phrase-Dashboard zugreifen können, kann durch Implementierung der isPhraseDashboardHidden Option eingeschränkt werden. Diese Funktion entspricht der, die an die hidden Eigenschaft eines Feldes in Sanity übergeben wird. Sie erhält einen Kontext mit dem aktuellen Benutzer und Dokument und muss einen booleschen Wert zurückgeben.

Beispiel für die Einschränkung des Zugriffs auf das Phrase-Dashboard für Benutzer mit der admin Rolle:

const PHRASE_CONFIG = definePhraseOptions({
  // ...
  isPhraseDashboardHidden: (context) => {
    const isAdmin = (context.currentUser.roles || []).some(
      (r) => r.name === 'admin',
    )
    // Ausblenden, wenn kein Admin
    return !isAdmin
  },
})
War dieser Beitrag hilfreich?

Sorry about that! In what way was it not helpful?

The article didn’t address my problem.
I couldn’t understand the article.
The feature doesn’t do what I need.
Other reason.

Note that feedback is provided anonymously so we aren't able to reply to questions.
If you'd like to ask a question, submit a request to our Support team.
Thank you for your feedback.