TanStack
Core Guides

FlexRender (Vue) Guide

Column definitions can contain strings, VNodes, Vue components, or renderer functions for header, cell, footer, and aggregatedCell. Use the adapter's rendering utilities so each form is mounted correctly and receives its table context.

FlexRender vs flexRender

FlexRender is the recommended Vue component. Its shorthand props accept exactly one cell, header, or footer object:

vue
<script setup lang="ts">
import { FlexRender } from '@tanstack/vue-table'
</script>

<template>
  <th v-for="header in headerGroup.headers" :key="header.id">
    <FlexRender v-if="!header.isPlaceholder" :header="header" />
  </th>

  <td v-for="cell in row.getVisibleCells()" :key="cell.id">
    <FlexRender :cell="cell" />
  </td>
</template>

For cells, the component selects aggregatedCell for aggregated rows, falls back to cell, and renders nothing for grouping placeholders. Use :footer="header" for a header object from a footer group.

Tables created by createTableHook also expose an app-aware component as table.FlexRender. Because it is stored as a value, render it with Vue's dynamic component syntax:

vue
<component :is="table.FlexRender" :cell="cell" />

flexRender is the lower-level function for a renderable value and its props:

ts
import { flexRender } from '@tanstack/vue-table'

flexRender(cell.column.columnDef.cell, cell.getContext())

It passes primitive values through, preserves returned VNodes, and creates VNodes for Vue component objects. It does not choose grouped-cell renderers or suppress grouping placeholders.

The component still supports the older low-level render/props pair:

vue
<FlexRender :render="cell.column.columnDef.cell" :props="cell.getContext()" />

Prefer the cell, header, and footer shorthand for new code. Placeholder headers remain the caller's layout decision, so check header.isPlaceholder unless a spanning-header layout intentionally renders one.