How to Add Your Language

A step-by-step guide for volunteers, translators, and local Wikimedia communities to bring their regional language into the WikiNusa app.

Introduction: Two-File Modular Architecture

WikiNusa is built to revitalize and expand access to free knowledge in the regional and indigenous languages of Indonesia and neighboring regions. To make contributing accessible to everyone without requiring coding experience, WikiNusa uses a clean, two-file modular architecture.

You do not need to touch any Dart or Flutter source code. Each language community is fully defined by just two independent JSON files:

  • assets/communities/<language_code>.json — Community configuration file defining active Wikimedia projects, home portals, quick shortcuts, interactive modules, and custom article layout rules.
  • assets/translations/<language_code>.json — Localization file containing all user interface strings translated into your language.
🛡️ Built-in Fault Tolerance: Every community file is parsed in complete isolation. If a syntax mistake or typo occurs in one community's file, WikiNusa logs the issue and skips that specific language, ensuring the app remains perfectly stable and all other languages continue to function normally.
Step 1

Choose Your Language Code

Identify the official ISO 639 code (ISO 639-1, 639-2, or 639-3) that corresponds to your language's Wikimedia subdomain.

Examples of regional language codes supported or in progress:

  • ban — Balinese (Basa Bali)
  • ace — Acehnese (Bahsa Acèh)
  • mak — Makassarese (Basa Mangkasara')
  • min — Minangkabau (Baso Minang)
  • jv — Javanese (Basa Jawa)
  • su — Sundanese (Basa Sunda)
  • nia — Nias (Li Niha)
  • bbc — Batak Toba
  • btm — Batak Mandailing
Important: Both files must share the exact same code name:
assets/communities/<code>.json and assets/translations/<code>.json.
Step 2

Create the Community Manifest

Create a new file in assets/communities/ named <code>.json (for example: assets/communities/ban.json).

Here is a complete JSON template ready to copy and adapt:

{
  "code": "ban",
  "name": "Balinese",
  "nativeName": "Basa Bali",
  "direction": "ltr",
  "experimental": false,
  "defaultProject": "wikipedia",
  "projects": {
    "wikipedia": {
      "name": "Wikipédia",
      "articlePath": "https://ban.wikipedia.org/wiki/$1",
      "apiEndpoint": "https://ban.wikipedia.org/w/api.php",
      "mobileUrl": "https://ban.m.wikipedia.org",
      "isIncubator": false,
      "homePageSections": {
        "featuredArticle": "mp-tfa",
        "featuredImage": "mp-tfp",
        "doYouKnow": "mp-dyk",
        "onThisDay": "mp-otd"
      },
      "shortcuts": [
        "Portal:Komunitas",
        "Istimewa:Perubahan_terbaru",
        "Wikipédia:Pitulung"
      ],
      "portals": [
        {
          "title": "Budaya",
          "page": "Portal:Budaya"
        }
      ],
      "modules": {
        "chat": true,
        "newsletter": false,
        "crosswords": false,
        "language_course": false,
        "gallery": false
      }
    },
    "wiktionary": {
      "name": "Wikikamus",
      "articlePath": "https://ban.wiktionary.org/wiki/$1",
      "apiEndpoint": "https://ban.wiktionary.org/w/api.php",
      "mobileUrl": "https://ban.m.wiktionary.org",
      "isIncubator": false,
      "homePageSections": {
        "featuredWord": "mp-word-day-body",
        "newWords": "mp-new-words-body"
      },
      "shortcuts": [
        "Wikikamus:Pitulung"
      ]
    }
  }
}

Configuration Parameter Reference

Parameter Type Required Description
code String Yes ISO language code (e.g. "ban").
name String Yes English or common name of the language.
nativeName String Yes Autonym / native name of the language (e.g. "Basa Bali").
direction String No Reading direction: "ltr" (left-to-right) or "rtl". Default: "ltr".
experimental Boolean No Whether the language is experimental (true) or graduated/stable (false). Experimental languages display an "Experiment" badge in Language Settings. Default: false for primary languages (id, nia), true for others. Set "experimental": false to graduate a language without an app release.
defaultProject String No Default starting project ("wikipedia", "wiktionary", or "wikibooks").
projects Object Yes Map of active Wikimedia projects for this language.

Project Details

  • name: Localized project title (e.g. "Wikipédia").
  • articlePath: URL pattern containing the $1 title placeholder.
  • apiEndpoint: MediaWiki Action API endpoint URL.
  • mobileUrl: Mobile domain URL.
  • isIncubator: Set to true if the project is still hosted on Wikimedia Incubator, and include incubatorPrefix (e.g. "Wp/btm/").
  • homePageSections: Map of section selectors used to extract and render clean mobile cards on the Home screen instead of unformatted desktop HTML.
  • shortcuts: Wiki page titles to showcase in the Quick Shortcuts drawer.
  • portals: Thematic portals to display as explore cards on the home screen.
  • modules: Feature switches for your community (chat, newsletter, crosswords, language_course, gallery).

Home Page Sections Configuration (homePageSections)

WikiNusa parses the wiki's Main Page (e.g., Halaman_Utama, Main_Page, or Wikipédia:Pendhapa) and transforms individual content sections into native, touch-friendly cards.

Supported Section Keys

Key Project Description Localized Heading
featuredArticle Wikipedia Featured Article / Lead Story "FEATURED ARTICLE" / "ARTIKEL PILIHAN"
featuredImage Wikipedia / Wiktionary Picture of the Day / Featured Media "FEATURED IMAGE" / "GAMBAR PILIHAN"
doYouKnow Wikipedia / Wiktionary "Did You Know" bullet facts "DID YOU KNOW" / "TAHUKAH ANDA"
inTheNews Wikipedia Current events & headlines "IN THE NEWS" / "PERISTIWA TERKINI"
onThisDay Wikipedia Historical anniversaries "ON THIS DAY" / "HARI INI DALAM SEJARAH"
onThisMonth Wikipedia Monthly anniversaries "ON THIS MONTH" / "BULAN INI DALAM SEJARAH"
featuredList Wikipedia Featured lists & indices "FEATURED LIST" / "DAFTAR PILIHAN"
featuredWord Wiktionary Word of the day / Selected lemma "WORD OF THE DAY" / "LEMA TERPILIH"
newWords Wiktionary Newly created dictionary entries "NEW WORDS" / "LEMA BARU"
featuredBook Wikibooks Featured instructional book "FEATURED BOOK" / "BUKU PILIHAN"
newBooks Wikibooks New books in development "NEW BOOKS" / "BUKU BARU"

Section Selector Formats

You can configure each section using either a Simple String or a Detailed Object:

1. Simple String (CSS ID or Class)

"homePageSections": {
  "featuredArticle": "mp-tfa",
  "featuredImage": "mp-tfp",
  "doYouKnow": "mp-dyk",
  "onThisDay": "mp-otd"
}
Note: IDs can be written with or without a # prefix (e.g. "mp-tfa" or "#mp-tfa"). WikiNusa includes resilient fallbacks between mp- (desktop) and mf- (MobileFrontend) prefix variants.

2. Detailed Object (Precision Extraction)

Use this format when the wiki's section contains extraneous navigation links, archive footers, or unstyled tables:

"homePageSections": {
  "featuredArticle": {
    "selector": "mf-artikelpilihan",
    "keep": "p",
    "firstOnly": true
  },
  "doYouKnow": {
    "selector": "mf-tahukahanda",
    "keep": "ul",
    "firstOnly": true
  }
}
  • selector (String, Required): The CSS selector targeting the section container.
  • keep (String or Array of Strings, Optional): Specific HTML tags to retain (e.g., "p" to keep only paragraphs, or ["p", "ul"]).
  • firstOnly (Boolean, Optional): When true, extracts only the first matching element within the section, pruning trailing archive links and category blocks.
💡 Recommendation: To standardize your wiki community's Main Page templates with modern CSS classes, refer to the CSS Standardization Proposal.

Display Rules & The "Keep" Override

WikiNusa applies default cleanup rules from assets/communities/_global.json to strip desktop navigation sidebars, edit tags, and intrusive banners for a crisp mobile reading experience.

However, if your community wiki needs to preserve elements that are removed by global rules (such as infoboxes or special tables), specify them in the keep array:

"projects": {
  "wikipedia": {
    "name": "Wikipédia",
    "articlePath": "https://ban.wikipedia.org/wiki/$1",
    "apiEndpoint": "https://ban.wikipedia.org/w/api.php",
    "keep": [".infobox", ".nomobile"],
    "remove": [".reflist"]
  }
}
  • keep: CSS selectors that must never be stripped or hidden for this language, overriding global rules.
  • remove: Additional CSS selectors to completely strip from this project's articles.
  • hide: Additional CSS selectors to hide using CSS styles.
Step 3

Create the Translation File

Duplicate assets/translations/en.json (or id.json) and save it as assets/translations/<code>.json (e.g. assets/translations/ban.json).

Open the file and translate the text strings on the right-hand side of each colon (:):

{
  "app_name": "WikiNusa",
  "home": "Kaca Utama",
  "shortcuts": "Pintasan",
  "random": "Acak",
  "bookmarks": "Tanda Buku",
  "search_hint": "Rereh ring WikiNusa...",
  "share": "Bagikan",
  "edit": "Uwah",
  "view_in_browser": "Cingak ring Browser",
  "table_of_contents": "Daftar Isi",
  "drawer_modules": "Modul Komunitas",
  "drawer_language": "Basa",
  "drawer_appearance": "Tampilan",
  "drawer_font_size": "Ukuran Aksara",
  "drawer_about": "Indik Aplikasi"
}
Tip: Do not change keys on the left (such as "home" or "bookmarks"). Only translate the localized text values on the right.
Step 4

Validate Your JSON Files

Before submitting, confirm both JSON files are syntactically valid:

  1. Ensure all curly braces {} and brackets [] properly open and close.
  2. Verify there are no trailing commas after the last property of an object or array.
  3. Validate using an online linter such as jsonlint.com or the jq CLI tool:
jq . assets/communities/ban.json
jq . assets/translations/ban.json
Step 5

Test Locally (Optional)

If you have Flutter installed on your workstation:

  1. Run automated unit and integration tests:
    flutter test
  2. Run the app on your emulator or connected device:
    flutter run
  3. Open the side drawer → tap Language → enable your new language. Your language will immediately appear in the UI and home page!
Step 6

Submit a Pull Request

Share your contribution back to the community via GitHub:

  1. Fork the WikiNusa repository on GitHub: github.com/sslaia/wikinusa.
  2. Create a new branch on your local clone:
    git checkout -b feat/add-balinese-language
  3. Stage and commit your two new JSON files:
    git add assets/communities/ban.json assets/translations/ban.json
    git commit -m "feat(community): add Balinese (ban) manifest and translations"
  4. Push to your personal fork:
    git push origin feat/add-balinese-language
  5. Open a Pull Request (PR) against the upstream repository. The WikiNusa team will review and bundle your language into the upcoming release!
↑