How to Add Your Language
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.
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 Tobabtm— Batak Mandailing
assets/communities/<code>.json and assets/translations/<code>.json.
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$1title placeholder.apiEndpoint: MediaWiki Action API endpoint URL.mobileUrl: Mobile domain URL.isIncubator: Set totrueif the project is still hosted on Wikimedia Incubator, and includeincubatorPrefix(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"
}
# 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): Whentrue, extracts only the first matching element within the section, pruning trailing archive links and category blocks.
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.
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"
}
"home" or "bookmarks"). Only translate the localized text values on the right.
Validate Your JSON Files
Before submitting, confirm both JSON files are syntactically valid:
- Ensure all curly braces
{}and brackets[]properly open and close. - Verify there are no trailing commas after the last property of an object or array.
- Validate using an online linter such as jsonlint.com or the
jqCLI tool:
jq . assets/communities/ban.json
jq . assets/translations/ban.json
Test Locally (Optional)
If you have Flutter installed on your workstation:
- Run automated unit and integration tests:
flutter test - Run the app on your emulator or connected device:
flutter run - Open the side drawer → tap Language → enable your new language. Your language will immediately appear in the UI and home page!
Submit a Pull Request
Share your contribution back to the community via GitHub:
- Fork the WikiNusa repository on GitHub: github.com/sslaia/wikinusa.
- Create a new branch on your local clone:
git checkout -b feat/add-balinese-language - 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" - Push to your personal fork:
git push origin feat/add-balinese-language - Open a Pull Request (PR) against the upstream repository. The WikiNusa team will review and bundle your language into the upcoming release!