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:
| Language | Code |
|---|---|
| English | en |
| French | fr |
| Spanish | es |
| German | de |
| Portuguese | pt |
| Italian | it |
| Dutch | nl |
| Russian | ru |
| Japanese | ja |
| Chinese (Simplified) | zh |
| Korean | ko |
| Arabic | ar |
Automatically detect the user's preferred language from their browser:
detect-language.tsimport { detectUserLanguage } from "@simplist.blog/sdk"
const userLang = detectUserLanguage()
console.log(userLang) // 'en', 'fr', 'es', etc.Fetch content with automatic language fallback:
get-variant.tsimport { 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.tsimport { 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:
- Check if requested language variant exists → return it
- Check if fallback language variant exists → return it
- Return first available variant
- Return main article as last resort
Automatically select the best variant based on browser language:
get-best-variant.tsimport { 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.tsimport { 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.tsimport { 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.tsimport { 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.tsimport { 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.tsimport { 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}`)| Method | Description | Returns |
|---|---|---|
| Get complete variant object | ArticleVariant | Article | |
| Get title in user's language | string | |
| Get excerpt in user's language | string | null | |
| Get full content in user's language | string | |
| Get cover image in user's language | string | null | |
| Get language of selected content | LanguageCode | |
| Update user language preference | void | |
| Update default language | void |
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.tsinterface 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.tsimport { 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.tsximport { 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
}
}
}Articles API
Fetch article content
SEO Utilities
Generate multilingual sitemaps
Complete Examples
Full implementation guides