Examples

Simplist provides comprehensive multilingual support with 80+ languages, automatic browser language detection, and smart content variant management.

Articles in Simplist can have variants - translated versions of the same content. The SDK provides utilities to:

  • Detect user's browser language automatically
  • Select the best matching variant with fallback logic
  • Access translated content (title, excerpt, content, images)
  • Manage language preferences

The SDK supports 80+ languages including:

LanguageCode
Englishen
Frenchfr
Spanishes
Germande
Portuguesept
Italianit
Dutchnl
Russianru
Japaneseja
Chinese (Simplified)zh
Koreanko
Arabicar

Automatically detect the user's preferred language from their browser:

detect-language.ts
import { detectUserLanguage } from "@simplist.blog/sdk"

const userLang = detectUserLanguage()
console.log(userLang) // 'en', 'fr', 'es', etc.

Fetch content with automatic language fallback:

get-variant.ts
import { SimplistClient, getVariantOrDefault, detectUserLanguage } from "@simplist.blog/sdk"

// Uses SIMPLIST_API_KEY from environment variables
const client = new SimplistClient()
const response = await client.articles.get('my-article')
const article = response.data

// Get user's language
const userLang = detectUserLanguage()

// Get content in user's language (or fallback to English)
const content = getVariantOrDefault(article, userLang, 'en')

console.log(content.title)
console.log(content.content)

Get article content in a specific language with fallback:

get-variant-or-default.ts
import { getVariantOrDefault } from "@simplist.blog/sdk"

const article = response.data

// Get French variant, fallback to English
const frenchContent = getVariantOrDefault(article, 'fr', 'en')

// Get Spanish variant, fallback to English
const spanishContent = getVariantOrDefault(article, 'es', 'en')

Fallback Logic:

  1. Check if requested language variant exists → return it
  2. Check if fallback language variant exists → return it
  3. Return first available variant
  4. Return main article as last resort

Automatically select the best variant based on browser language:

get-best-variant.ts
import { getBestMatchingVariant } from "@simplist.blog/sdk"

const article = response.data

// Automatically detects user language and returns best match
const content = getBestMatchingVariant(article)
console.log(content.title)

// Force a specific language with fallback
const frenchContent = getBestMatchingVariant(article, 'fr', 'en')
console.log(frenchContent.title)

Check if an article has a translation in a specific language:

has-variant.ts
import { hasVariant } from "@simplist.blog/sdk"

const article = response.data

if (hasVariant(article, 'fr')) {
  console.log('French translation available!')
} else {
  console.log('No French translation')
}

Get all available languages for an article:

get-all-languages.ts
import { getAllLanguages } from "@simplist.blog/sdk"

const article = response.data
const languages = getAllLanguages(article)

console.log(languages) // ['en', 'fr', 'es', 'de']

Check if an article has any translations:

is-multilingual.ts
import { isMultilingual } from "@simplist.blog/sdk"

const article = response.data

if (isMultilingual(article)) {
  console.log('This article has translations')
} else {
  console.log('This article is single-language')
}

Get comprehensive information about available variants:

get-variant-metadata.ts
import { getVariantMetadata } from "@simplist.blog/sdk"

const article = response.data
const metadata = getVariantMetadata(article)

console.log(metadata)
// {
//   languages: ['en', 'fr', 'es'],
//   count: 3,
//   isMultilingual: true,
//   hasVariants: true
// }

The VariantSelector class provides a clean API for managing multilingual content:

variant-selector.ts
import { SimplistClient, VariantSelector } from "@simplist.blog/sdk"

// Uses SIMPLIST_API_KEY from environment variables
const client = new SimplistClient()

// Create selector with default language
const selector = new VariantSelector({
  defaultLanguage: 'en',
  userLanguage: 'fr' // Optional: override auto-detection
})

const response = await client.articles.get('my-article')
const article = response.data

// Get content in user's language
const title = selector.getTitle(article)
const excerpt = selector.getExcerpt(article)
const content = selector.getFullContent(article)
const coverImage = selector.getCoverImage(article)
const selectedLang = selector.getSelectedLanguage(article)

console.log(`Showing content in: ${selectedLang}`)

MethodDescriptionReturns
Get complete variant objectArticleVariant | Article
Get title in user's languagestring
Get excerpt in user's languagestring | null
Get full content in user's languagestring
Get cover image in user's languagestring | null
Get language of selected contentLanguageCode
Update user language preferencevoid
Update default languagevoid

Here's a full Next.js implementation with language detection and variant selection:

import { SimplistClient, VariantSelector } from "@simplist.blog/sdk"
import type { Metadata } from "next"

// Uses SIMPLIST_API_KEY from environment variables
const client = new SimplistClient()

export async function generateMetadata({
  params
}: {
  params: Promise<{ slug: string }>
}): Promise<Metadata> {
  const slug = await params.slug;

  const response = await client.articles.get(slug)
  const article = response.data

  // Create selector with English fallback
  const selector = new VariantSelector({ defaultLanguage: 'en' })

  const title = selector.getTitle(article)
  const excerpt = selector.getExcerpt(article)
  const coverImage = selector.getCoverImage(article)
  const lang = selector.getSelectedLanguage(article)

  return {
    title,
    description: excerpt ?? undefined,
    openGraph: {
      title,
      description: excerpt ?? undefined,
      images: coverImage ? [coverImage] : undefined,
      locale: lang
    }
  }
}

Build a language switcher component:

language-switcher.tsx
"use client"

import { Article, getAllLanguages } from "@simplist.blog/sdk"
import { useState } from "react"

export function LanguageSwitcher({ article }: { article: Article }) {
const [selectedLang, setSelectedLang] = useState('en')
const availableLanguages = getAllLanguages(article)

  // If no translations, don't show switcher
  if (availableLanguages.length === 0) {
    return null
  }

  // Add main article language
  const allLanguages = ['en', ...availableLanguages]

  return (
    <div className="flex gap-2">
      {allLanguages.map(lang => (
        <button
          key={lang}
          onClick={() => setSelectedLang(lang)}
          className={selectedLang === lang ? 'font-bold' : ''}
        >
          {lang.toUpperCase()}
        </button>
      ))}
    </div>
  )

}

Each variant includes:

article-variant-type.ts
interface ArticleVariant {
  lang: LanguageCode                // Language code
  title: string                     // Translated title
  excerpt: string | null            // Translated excerpt
  content: string                   // Translated content
  coverImage: string | null         // Language-specific cover image
  wordCount: number                 // Word count for this variant
  characterCount: number            // Character count
  lineCount: number                 // Line count
  readTimeMinutes: number           // Reading time
  createdAt: string                 // Variant creation timestamp
  updatedAt: string                 // Last update timestamp
}

Variants are stored in the variants property of an article:

access-variants.ts
import { SimplistClient } from "@simplist.blog/sdk"

// Uses SIMPLIST_API_KEY from environment variables
const client = new SimplistClient()
const response = await client.articles.get('my-article')
const article = response.data

// Access variants directly
if (article.variants) {
const frenchVariant = article.variants['fr']
const spanishVariant = article.variants['es']

  if (frenchVariant) {
    console.log(frenchVariant.title)
    console.log(frenchVariant.content)
  }

}

For SSR (Server-Side Rendering), detect language from Accept-Language header:

server-side-detection.ts
// In Next.js App Router
import { headers } from "next/headers"

export default async function Page() {
const headersList = headers()
const acceptLanguage = headersList.get('accept-language')

  // Parse Accept-Language header
  const userLang = acceptLanguage?.split(',')[0]?.split('-')[0] || 'en'

  // Use with VariantSelector
  const selector = new VariantSelector({
    userLanguage: userLang,
    defaultLanguage: 'en'
  })

  // ... rest of your code

}

Store user language preference in localStorage:

client-preferences.ts
"use client"

import { VariantSelector } from "@simplist.blog/sdk"
import { useEffect, useState } from "react"

export function useLanguagePreference() {
const [lang, setLang] = useState<string>('en')

  useEffect(() => {
    // Load from localStorage
    const saved = localStorage.getItem('preferred-language')
    if (saved) {
      setLang(saved)
    }
  }, [])

  const updateLanguage = (newLang: string) => {
    localStorage.setItem('preferred-language', newLang)
    setLang(newLang)
  }

  return { lang, updateLanguage }

}

Use proper HTML lang attributes and hreflang links:

multilingual-seo.tsx
import { SimplistClient, VariantSelector, getAllLanguages } from "@simplist.blog/sdk"
import { Metadata } from "next"

const client = new SimplistClient()

export async function generateMetadata({ params }: {
params: { slug: string }
}): Promise<Metadata> {
const response = await client.articles.get(params.slug)
const article = response.data

  const selector = new VariantSelector()
  const selectedLang = selector.getSelectedLanguage(article)
  const allLanguages = ['en', ...getAllLanguages(article)]

  // Generate alternate links for all languages
  const alternates = allLanguages.reduce((acc, lang) => {
    acc[lang] = `https://myblog.com/${lang}/articles/${params.slug}`
    return acc
  }, {} as Record<string, string>)

  return {
    alternates: {
      languages: alternates
    },
    openGraph: {
      locale: selectedLang
    }
  }

}

Quick Help

Use the same URL for all languages and serve content based on Accept-Language header or user preference. This keeps SEO simple and avoids duplicate content issues.
Always use getVariantOrDefault() which automatically falls back to your default language. This ensures users always see content even if a translation is incomplete.
Yes! Store the preference in localStorage or cookies, then pass it to getVariant(). Override automatic detection with manual selection for better UX.

Command Palette

Search for a command to run...