Field Micro Frontend (MFE)
Penjelasan setiap key pada deklarasi field EXTERNAL_MICRO_FRONTEND_FORM — mana yang dieksekusi platform, mana yang harus dibaca sendiri oleh komponen MFE, serta cara memakai additional_mfe_config.
Komponen Micro Frontend pada Form Builder memungkinkan Anda menyematkan aplikasi React sendiri ke dalam form AlurKerja. Halaman ini menjelaskan arti setiap key pada deklarasi field EXTERNAL_MICRO_FRONTEND_FORM, siapa yang mengonsumsi key tersebut (platform atau komponen MFE), dan kenapa sebagian key terlihat "tidak berefek" — kasus paling sering: "disabled": true yang ternyata tetap bisa diisi user.
Untuk langkah membuat dan mem-publish addon MFE (setup Module Federation, index.json, publish), lihat dokumentasi Addon AlurKerja pada bagian Studio. Halaman ini fokus pada deklarasi field-nya saja.
Contoh Deklarasi Lengkap
{
"ui_type": "EXTERNAL_MICRO_FRONTEND_FORM",
"label": {
"en": "External Micro Frontend Form",
"id": "Formulir Micro Frontend Eksternal"
},
"name": "email_raf_user_form_form_user_form",
"url": "https://api.staging.alurkerja.com/api/v1/integration/addons/email_form/views/remoteEntry.js",
"component_scope": "email_form",
"component_name": "create_view",
"height": "",
"width": "100%",
"disabled": false,
"logic": {
"expression": ""
},
"constraints": {
"required": false,
"required_if": { "expression": "" }
},
"additional_mfe_config": {
"addonId": "1189"
}
}Prinsip Utama: Host Hanya Menitipkan, MFE yang Merender
Ada dua kelompok key dalam deklarasi di atas, dan ini sumber semua kebingungan:
| Kelompok | Siapa yang mengeksekusi | Contoh key |
|---|---|---|
| Loader keys | Platform AlurKerja (host) — dipakai untuk menemukan & memuat bundle Module Federation, lalu menentukan ukuran container-nya. | url, component_scope, component_name, ui_type, height, width |
| Payload keys | Komponen MFE Anda — host hanya menyalin seluruh objek deklarasi ini menjadi prop props.item, lalu berhenti di situ. | label, disabled, constraints, placeholder, tooltip, additional_mfe_config, dan key custom apa pun |
Untuk field bawaan AlurKerja (TEXT_FIELD, SELECT, dll.), host yang merender input-nya, sehingga host bisa memaksakan disabled/required/placeholder. Untuk EXTERNAL_MICRO_FRONTEND_FORM, yang merender adalah React component milik Anda. Host tidak punya cara memaksa <input> di dalam JSX pihak ketiga menjadi disabled — maka semua payload key statusnya advisory: hanya data titipan.
Payload key bukan perintah ke platform, melainkan parameter yang harus dibaca sendiri oleh komponen MFE.
Bentuk prop yang diterima komponen (lihat views/src/type/AlurkerjaType.ts pada project addon):
export interface AlurkerjaMfeInputProps {
props: {
form: { setValue, register, control, watch, getValues };
item: InputType; // ← SELURUH JSON deklarasi di atas masuk ke sini
};
alurkerjaParams: {
apiBaseUrl?: string;
token: string;
activeTenant: string;
probis: string;
taskId: string;
[key: string]: any;
};
}Tabel Referensi Key
| Key | Wajib | Dikonsumsi oleh | Fungsi & catatan |
|---|---|---|---|
ui_type | ✅ | Host | Harus persis EXTERNAL_MICRO_FRONTEND_FORM. Ini yang membuat host memakai loader Module Federation alih-alih renderer field bawaan. |
name | ✅ | Host + form | Nama field di form state. Key yang dipakai form.setValue(name, ...) / getValues(name) dan yang tersimpan ke variabel proses. Harus unik dalam satu form. |
label.en / label.id | ➖ | MFE | Label multi-bahasa. Host tidak otomatis mencetak judul di atas MFE — jika butuh judul, render sendiri dari item.label. |
url | ✅ | Host | URL absolut ke remoteEntry.js hasil build. Salah host/protokol → MFE blank tanpa error di form. |
component_scope | ✅ | Host | Nama global scope Module Federation. Harus sama dengan component_scope di index.json dan name di ModuleFederationPlugin (views/webpack.config.js). |
component_name | ✅ | Host | Nama modul yang di-exposes, tanpa prefix ./. Contoh: exposes: { './analize_nota_view': ... } → tulis analize_nota_view. Salah ketik = MFE tidak muncul. |
height | ➖ | Host | Tinggi container. String CSS ("400px", "100%"). Kosong = tinggi mengikuti konten. |
width | ➖ | Host | Lebar container. String CSS. Umumnya "100%". |
disabled | ➖ | MFE | Niatnya "field read-only" (misalnya saat form di tahap review/approval). Tidak dipaksakan host — lihat bagian berikutnya. |
constraints.required | ➖ | MFE | Sama seperti disabled: validasi wajib-isi harus Anda daftarkan sendiri lewat form.register(name, { required: ... }). |
placeholder, tooltip, defaultValue | ➖ | MFE | Ikut terkirim di item, tapi tidak ada efek otomatis. Baca manual bila perlu. |
additional_mfe_config | ➖ | MFE | Kantong konfigurasi bebas — cara resmi mengirim parameter custom ke komponen. |
edit_tabs.mfeConfig.additional_mfe_config | ➖ | Form builder (UI) | Deklarasi agar form builder menampilkan tab editor untuk mengisi additional_mfe_config. Ini metadata untuk UI konfigurator, bukan nilai yang dibaca komponen. Nilai finalnya tetap ditulis ke additional_mfe_config di level atas. |
Kenapa disabled: true Tidak Terimplementasi?
Karena tidak ada bug di platform — disabled memang tidak pernah ditegakkan (enforced) oleh host untuk MFE. Host hanya menyalinnya ke props.item.disabled. Jika komponennya tidak membaca nilai itu, tidak ada yang berubah di layar.
Perbandingan dua komponen pada project addon:
| Komponen | Baca item.disabled? | Hasil saat "disabled": true |
|---|---|---|
TeamFormView.tsx | ✅ Ya | Header, form input, tombol tambah, dan tombol hapus disembunyikan → benar-benar read-only. |
AnalizeNotaView.tsx | ❌ Tidak (hanya baca additional_mfe_config) | Tombol "Analisa" tetap aktif, user tetap bisa upload & submit. |
Jadi checklist Disabled di konfigurator addon itu valid dan tersimpan; yang belum ada adalah implementasinya di sisi komponen. Ini keputusan developer per-komponen, bukan setting yang hilang.
Cara Menghormati disabled di Komponen
Pola yang dipakai TeamFormView.tsx — sembunyikan kontrol input, tetap tampilkan datanya:
export default function MyView({ props, alurkerjaParams }: AlurkerjaMfeInputProps) {
const { form, item } = props;
const isReadOnly = Boolean(item.disabled);
return (
<div className="space-y-4">
{/* Kontrol input: sembunyikan saat read-only */}
{!isReadOnly && (
<button onClick={handleAnalyze} disabled={isLoading}>
Analisa Nota
</button>
)}
{/* Hasil / data: tetap tampil di kedua mode */}
{result && <ResultTable data={result} />}
</div>
);
}Tiga hal yang sering terlewat saat mengimplementasikan disabled:
-
Semua tombol aksi (submit, tambah, hapus, upload) ikut dimatikan — bukan hanya yang utama.
-
Validasi
requiredikut dilepas, supaya form read-only tidak macet saat submit:required: (!item.disabled && item.constraints?.required) ? 'Field wajib diisi' : false -
Alternatif dari menyembunyikan: teruskan ke atribut native/library —
<input disabled={isReadOnly} />atau<Select isDisabled={isReadOnly} />. Pilih satu gaya dan konsisten dalam satu komponen.
Konfigurasi Tambahan: additional_mfe_config
Ini jalur resmi untuk mengirim parameter custom dari deklarasi addon ke komponen, tanpa perlu menambah key baru ke skema field (key baru di luar skema berisiko dibuang oleh validator platform).
1. Deklarasikan di JSON field:
{
"ui_type": "EXTERNAL_MICRO_FRONTEND_FORM",
"name": "analyze_receipt",
"component_name": "analize_nota_view",
"additional_mfe_config": {
"addonId": "1189",
"targetField": "total_amount",
"maxFiles": "5",
"autoAnalyze": "false"
}
}2. Baca di komponen:
const item = props.item;
const addonId = item.additional_mfe_config?.addonId ?? 3;Aturan Main
-
Selalu pakai optional chaining + default. Konfigurasi/instance lama bisa saja belum punya key-nya:
item.additional_mfe_config?.maxFiles ?? 5. -
Nilai dari form builder masuk sebagai string. Perhatikan
"addonId": "1189"— bertanda kutip. Konversi eksplisit sebelum dipakai sebagai angka atau boolean:const maxFiles = Number(item.additional_mfe_config?.maxFiles ?? 5); const autoAnalyze = item.additional_mfe_config?.autoAnalyze === 'true'; // JANGAN Boolean("false") -
Jangan simpan rahasia di sini. Isinya terkirim ke browser dan terbaca di DevTools. Token/API key taruh di
configaddon (index.json) yang dipakai oleh script Python di sisi server. -
Gunakan
camelCaseuntuk key-nya, mengikutiaddonIdyang sudah ada. -
Dokumentasikan setiap key baru di README komponen — konfigurator addon tidak punya deskripsi field untuk kantong bebas ini, jadi README-lah satu-satunya sumber kebenaran.
-
Agar tab pengisiannya muncul di form builder, sertakan juga:
"edit_tabs": { "mfeConfig": { "additional_mfe_config": {} } }
additional_mfe_config terkirim ke browser dan dapat dibaca siapa pun lewat DevTools. Jangan pernah menaruh token, API key, atau kredensial apa pun di dalamnya.
Sumber Nilai additional_mfe_config
Nilai additional_mfe_config diisi lewat form builder: klik dua kali komponen Micro Frontend untuk membuka Edit Element, lalu buka tab Mfe Config. Tambahkan pasangan key/value melalui tombol Add Entry — hasilnya dapat langsung dilihat pada bagian Preview dalam bentuk JSON.
Key Lain yang Dikenali Platform
Pemetaan antara field di konfigurator form builder dan key JSON yang dihasilkan:
| Tab | Label di UI | Key JSON | Tipe | Default | Dikirim ke MFE? |
|---|---|---|---|---|---|
| General | Name (EN/ID) | label.en / label.id | string | — | ✅ via item |
| General | Key | name | string | external_micro_frontend_form_<rand> | ✅ via item |
| General | Url | url | string | '' | ⚙️ dipakai loader (bukan prop) |
| General | Component Scope | component_scope | string | '' | ⚙️ dipakai loader |
| General | Component Name | component_name | string | '' | ⚙️ dipakai loader |
| General | Height | height | string | 500px | ✅ (wrapper style) |
| General | Width | width | string | 100% | ✅ (wrapper style) |
| General | Disabled | disabled | boolean | false | ✅ via item |
| Logic | Hide If | logic.expression | string | '' | ✅ via item |
| Validation | Required | constraints.required | boolean | false | ✅ via item |
| Validation | Required If | constraints.required_if.expression | string | '' | ✅ via item |
| Mfe Config | Configuration (key/value) | additional_mfe_config | object Record<string,string> | {} | ✅ via item |
FAQ
Saya sudah mencentang Disabled, kenapa field MFE masih bisa diisi?
Karena disabled tidak ditegakkan oleh platform untuk field MFE — nilainya hanya dititipkan ke props.item.disabled. Komponen MFE harus membacanya sendiri. Lihat Cara Menghormati disabled di Komponen.
MFE saya tidak muncul sama sekali (blank), apa yang perlu diperiksa?
Periksa ketiga loader key ini: url harus URL absolut yang benar ke remoteEntry.js, component_scope harus sama persis dengan name di ModuleFederationPlugin dan component_scope di index.json, serta component_name harus ditulis tanpa prefix ./.
Bagaimana cara mengirim parameter custom ke komponen MFE?
Gunakan additional_mfe_config. Jangan menambah key baru di luar skema field karena berisiko dibuang oleh validator platform. Lihat Konfigurasi Tambahan.
Kenapa nilai boolean dari additional_mfe_config selalu bernilai true?
Karena semua nilai dari form builder masuk sebagai string. Boolean("false") menghasilkan true. Bandingkan secara eksplisit: item.additional_mfe_config?.autoAnalyze === 'true'.
Apakah label yang saya isi otomatis tampil di atas komponen MFE?
Tidak. Host tidak mencetak judul untuk field MFE. Jika butuh judul, render sendiri di komponen dari item.label.
