Use-case: Suppose in your application you have 10 tables to show. So instead of writing code for each table, you can think of this dynamic/reusable table.
Create Dynamic/Reusable Table
- Define a Custom Metadata Type:
Create a Custom Metadata Type named Table_Column_Metadata__mdt. Add fields to store column information such as API_Name__c (API name of the field), Label__c (column label), and any other necessary fields.
- Populate Custom Metadata Records:
Create records in your Custom Metadata Type to define the columns you want to display in the table. Each record should contain the information for each column, including the API name of the field and the label.
- Create the DynamicTable LWC:
dynamicTableLWC.html:
<template>
<table class="slds-table slds-table_bordered slds-table_cell-buffer">
<thead>
<tr class="slds-text-title_caps">
<template for:each={tableColumns} for:item="column" key={column.apiName}>
<th key={column.apiName} scope="col">{column.label}</th>
</template>
</tr>
</thead>
<tbody>
<template for:each={tableData} for:item="row" key={row.Id}>
<tr key={row.Id}>
<template for:each={tableColumns} for:item="column">
<td key={column.apiName}>{row[column.apiName]}</td>
</template>
</tr>
</template>
</tbody>
</table>
</template>
dynamicTableLWC.js:
import { LightningElement, api, wire } from 'lwc';
import getTableColumnMetadata from '@salesforce/apex/DynamicTableController.getTableColumnMetadata';
export default class DynamicTableLWC extends LightningElement {
@api tableData; // List of records passed to the component
@wire(getTableColumnMetadata)
wiredColumns({ error, data }) {
if (data) {
this.tableColumns = data.map(column => ({
apiName: column.API_Name__c,
label: column.Label__c
}));
} else if (error) {
console.error('Error loading table column metadata', error);
}
}
}
Create the Apex Controller:
DynamicTableController.apxc:
public with sharing class DynamicTableController {
@AuraEnabled(cacheable=true)
public static List<Table_Column_Metadata__mdt> getTableColumnMetadata() {
return [SELECT API_Name__c, Label__c FROM Table_Column_Metadata__mdt];
}
}
Use the Dynamic Table Component:
In your parent component where you want to use the dynamic table, pass the list of records to the tableData attribute of the c-dynamic-table component:
<c-dynamic-table table-data={yourListOfRecords}></c-dynamic-table>
In this example, replace yourListOfRecords with the actual list of records that you want to display in the dynamic table.
This implementation fetches the column information from Custom Metadata and uses that information to dynamically generate the table headers and cell values based on the provided list of records. Make sure to adjust field names, API names, and other details to match your Custom Metadata Type configuration and your specific use case.

