Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/MC-World-Compressor/Frontend/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The translation system provides functions and hooks for accessing localized strings in both server and client components. Location: lib/translations.js

Translation Functions

getPageTranslations(locale, page)

Retrieve all translations for a specific page. Type: Server & Client Function Signature:
function getPageTranslations(
  locale: string,
  pageName: string
): Record<string, any>
Parameters:
locale
string
required
The locale code (e.g., ‘en’, ‘es’, ‘hi’, ‘ar’)
pageName
string
required
The page key from translation files (e.g., ‘home’, ‘upload’, ‘status’, ‘download’)
Returns:
translations
object
Object containing all translation strings for the specified page
Implementation:
export function getPageTranslations(locale, pageName) {
  return translations[locale]?.[pageName] || translations.en?.[pageName] || {};
}
Usage Example (Server Component):
import { getPageTranslations } from '@/lib/translations';

export default async function Inicio({ params }) {
  const { locale } = await params;
  const t = getPageTranslations(locale, 'home');

  return (
    <div>
      <h1>{t.title}</h1>
      <p>{t.subtitle}</p>
      <p>{t.description}</p>
      <Link href={`/${locale}/upload`}>
        {t.compressButton}
      </Link>
    </div>
  );
}
Translation File Structure:
{
  "home": {
    "title": "MC World Compressor",
    "subtitle": "Reduce your Minecraft world size by up to",
    "description": "Fast, free, and easy to use",
    "compressButton": "Compress Your World"
  }
}
Accessing Nested Properties:
const t = getPageTranslations('en', 'home');

console.log(t.title);           // "MC World Compressor"
console.log(t.compression.moreThanZip); // Nested access

useTranslations(locale)

React hook for accessing translations with variable interpolation support. Type: Client-Side Hook Signature:
function useTranslations(locale: string): {
  t: (key: string, vars?: object | string) => string
}
Parameters:
locale
string
default:"en"
The locale code for translations
Returns:
t
function
Translation function that accepts a key and optional variables
Implementation:
export function useTranslations(locale = "en") {
  const t = (key, varsOrDefault = key) => {
    let translation = getNestedTranslation(translations[locale], key) 
      || getNestedTranslation(translations.en, key) 
      || key;
    
    // Handle variable interpolation
    if (typeof varsOrDefault === 'object' && varsOrDefault !== null) {
      Object.entries(varsOrDefault).forEach(([k, v]) => {
        translation = translation.replace(
          new RegExp(`{{\\s*${k}\\s*}}`, "g"),
          v
        );
      });
    }
    return translation;
  };
  return { t };
}
Usage Example (Client Component):
'use client';

import { useTranslations } from '@/lib/translations';

export default function UploadPage({ params }) {
  const [locale, setLocale] = useState('en');
  const { t } = useTranslations(locale);

  return (
    <div>
      <h1>{t('upload.title')}</h1>
      <p>{t('upload.dragDrop')}</p>
      <button>{t('upload.upload')}</button>
    </div>
  );
}
Variable Interpolation:
const { t } = useTranslations('en');

// Translation with variables
t('status.queuePositionTotal', { posicion: 5, total: 10 })
// Output: "Position 5 of 10 in queue"

// Translation file:
{
  "status": {
    "queuePositionTotal": "Position {{ posicion }} of {{ total }} in queue"
  }
}
Fallback Behavior:
const { t } = useTranslations('es');

// 1. First tries Spanish translation
// 2. Falls back to English if not found
// 3. Returns key itself if neither exists

t('missing.key') // Returns: "missing.key"

getTranslation(locale, key, defaultValue)

Direct translation lookup with default value support. Type: Server & Client Function Signature:
function getTranslation(
  locale: string,
  key: string,
  defaultValue?: string
): string
Parameters:
locale
string
required
The locale code
key
string
required
Dot-notated translation key (e.g., ‘upload.title’)
defaultValue
string
default:"key"
Fallback value if translation not found
Returns:
translation
string
The translated string or default value
Implementation:
export function getTranslation(locale, key, defaultValue = key) {
  const translation = getNestedTranslation(translations[locale], key);
  return translation || getNestedTranslation(translations.en, key) || defaultValue;
}
Usage Example:
import { getTranslation } from '@/lib/translations';

const title = getTranslation('es', 'upload.title', 'Upload');
console.log(title); // "Sube Tu Mundo" or "Upload" if not found

Helper Functions

getNestedTranslation(obj, path)

Internal helper for accessing nested object properties via dot notation. Signature:
function getNestedTranslation(obj: object, path: string): any
Implementation:
function getNestedTranslation(obj, path) {
  return path.split(".").reduce((current, key) => current?.[key], obj);
}
Example:
const obj = {
  upload: {
    errors: {
      sizeLimit: "File too large"
    }
  }
};

getNestedTranslation(obj, 'upload.errors.sizeLimit');
// Returns: "File too large"

Translation File Structure

Import and Export

import es from '../locales/es.json';
import en from '../locales/en.json';
import hi from '../locales/hi.json';
import ar from "../locales/ar.json";

const translations = { en, es, hi, ar };

Nested Structure Example

{
  "common": {
    "error": "Error",
    "goBack": "Go Back",
    "otherFiles": "other files"
  },
  "home": {
    "title": "MC World Compressor",
    "subtitle": "Reduce your Minecraft world size by up to",
    "compression": {
      "moreThanZip": "More than just ZIP compression",
      "steps": {
        "analyze": "Analyze",
        "optimize": "Optimize",
        "ready": "Download"
      }
    },
    "faq": {
      "title": "Frequently Asked Questions",
      "free": {
        "question": "Is it really free?",
        "answer": "Yes, completely free!"
      }
    }
  },
  "upload": {
    "title": "Upload Your World",
    "dragDrop": "Drag and drop your world file here",
    "errors": {
      "zipOnly": "Only .zip, .tar, or .tar.gz files are allowed",
      "sizeLimit": "File size must be less than 4GB"
    }
  },
  "status": {
    "title": "Compression Status",
    "queue": "In Queue",
    "processing": "Processing your world...",
    "ready": "Compression Complete!",
    "queuePositionTotal": "Position {{ posicion }} of {{ total }} in queue",
    "errors": {
      "connection": "Connection error. Please check your internet."
    }
  },
  "download": {
    "title": "Download Compressed World",
    "compressionRatio": "Compressed by <b>{{ porcentaje }}%</b>!"
  }
}

Usage Patterns

Pattern 1: Server Component with Page Translations

import { getPageTranslations } from '@/lib/translations';

export default async function Page({ params }) {
  const { locale } = await params;
  const t = getPageTranslations(locale, 'home');
  
  return (
    <div>
      <h1>{t.title}</h1>
      <p>{t.faq.free.question}</p>
    </div>
  );
}

Pattern 2: Client Component with Hook

'use client';
import { useTranslations } from '@/lib/translations';

export default function Component({ params }) {
  const [locale, setLocale] = useState('en');
  const { t } = useTranslations(locale);
  
  return <h1>{t('upload.title')}</h1>;
}

Pattern 3: Dynamic Translations with Variables

const { t } = useTranslations(locale);

const message = t('download.compressionRatio', { porcentaje: 50 });
// Returns: "Compressed by <b>50%</b>!"

Pattern 4: Error Messages with Fallbacks

const { t } = useTranslations(locale);

const errorMsg = error 
  ? t('upload.errors.sizeLimit') 
  : null;

if (file.size > MAX_SIZE) {
  setError(t('upload.errors.sizeLimit'));
}

Type Safety (Optional)

For TypeScript projects, you can add type definitions:
export type Locale = 'en' | 'es' | 'hi' | 'ar';

export interface TranslationFunction {
  (key: string): string;
  (key: string, vars: Record<string, string | number>): string;
}

export interface UseTranslationsReturn {
  t: TranslationFunction;
}

export function useTranslations(locale?: Locale): UseTranslationsReturn;
export function getPageTranslations(locale: Locale, page: string): Record<string, any>;
export function getTranslation(locale: Locale, key: string, defaultValue?: string): string;

Best Practices

Use getPageTranslations for server components (faster, no hook overhead)
Use useTranslations hook for client components with state/effects
Always provide English translations as fallback
Use variable interpolation for dynamic content: {{ variable }}
Keep translation keys organized by page/feature
Don’t call useTranslations conditionally - it’s a React hook
HTML in translations (like <b>) will be returned as string - use dangerouslySetInnerHTML if needed

Examples from Codebase

Example 1: Home Page (Server)

export default async function Inicio({ params }) {
  const { locale } = await params;
  const t = getPageTranslations(locale, 'home');

  return (
    <section className="py-20 text-center">
      <h1>{t.title}</h1>
      <p>{t.subtitle} <span>50%</span></p>
      <p>{t.description}</p>
      <Link href={`/${locale}/upload`}>
        {t.compressButton}
      </Link>
    </section>
  );
}

Example 2: Upload Page (Client)

'use client';

export default function HomePage({ params }) {
  const [locale, setLocale] = useState(null);
  const { t } = useTranslations(locale || 'en');
  
  const handleFileChange = (e) => {
    const file = e.target.files[0];
    if (!file.name.endsWith('.zip')) {
      setError(t('upload.errors.zipOnly'));
      return;
    }
    if (file.size > MAX_SIZE) {
      setError(t('upload.errors.sizeLimit'));
      return;
    }
  };
  
  return (
    <main>
      <h1>{t('upload.title')}</h1>
      <p>{t('upload.dragDrop')}</p>
    </main>
  );
}

Example 3: Status Page with Variables

const { t } = useTranslations(locale || 'en');

if (typeof cola === 'string' && cola.includes('/')) {
  const [posicion, total] = cola.split('/');
  const message = t('status.queuePositionTotal', { posicion, total });
  // "Position 5 of 10 in queue"
}

Example 4: Download Page with HTML

const porcentajeCompresion = 50;

<p
  dangerouslySetInnerHTML={{
    __html: t('download.compressionRatio', { porcentaje: porcentajeCompresion })
  }}
/>
// Renders: "Compressed by <b>50%</b>!"

Build docs developers (and LLMs) love