Programmable templates
LP reports are HTML, Tailwind and Handlebars – anything you can build on a web page, you can put in a PDF. With a full helper reference.
Reporting requirements are bespoke. Every fund has its own corporate identity, its own idea of what belongs on a company card, its own LP-specific appendices, and an LPA that dictates half the layout. Template builders with a fixed set of blocks run out of room quickly.
Fundra's reports are programmable templates: HTML, Tailwind classes and Handlebars expressions, rendered in a browser and printed to PDF. Anything you can build on a web page – layouts, charts, tables, custom typography, background artwork, your own brand system – you can put in a report.
While Fundra comes with a state-of-the-art template library built on industry best practices and leading fund reporting standards, every template is fully customizable. After all, LP reporting is more than a compliance exercise–it's your primary communication channel for building trust, demonstrating performance, and strengthening relationships with your investors.
Drafting the narrative
Layout is only half of a report. The other half is the writing, and Fundra drafts it from what the portfolio has already told you: the quarter's investor updates, board notes and KPI movements become a first draft of a company section or a portfolio summary, rather than a blank page.
Turn on Use my tone of voice and the model takes your previous reports into account, adapting to how your firm writes over time – so the draft sounds like your last LP letter instead of like a chatbot. It's a starting point to edit, not a send-ready document.
Tone of voice is currently in beta.
Templates aligned with Invest Europe reporting guidelines are available as a starting point if you'd rather not build a layout from scratch.
How a report is put together
A report is a set of sections, each with its own template, header, footer and page setup – orientation, margins and page size:
| Section | Typical content |
|---|---|
cover_page | Title page with fund branding |
executive_summary | The quarter's narrative |
capital_accounts | LP capital account statements – usually landscape |
portfolio_summary | The portfolio table – usually landscape |
company_card | One page per portfolio company, repeated across the fund |
back_page | Back cover, disclaimers, contact details |
Templates are edited in Settings → Reporting, with a live preview against real data and version history, so you can iterate on a layout without touching a live report.
Writing templates
Everything in Handlebars works – {{value}}, {{#if}}, {{#each}}, {{#with}}, partials, comments. On top of that, Fundra registers the helpers below.
Two conventions worth knowing:
- Helpers take hash arguments:
{{currency fmv decimals=1 currency="EUR"}}. Some also accept a positional shorthand –{{round value 2}}is the same as{{round value decimals=2}}. - An unknown helper renders a red badge in the preview rather than failing silently, so typos are visible while you're editing.
Text and formatting
| Helper | Result |
|---|---|
{{upper value}} | Uppercase |
{{trim value}} | Trims surrounding whitespace |
{{concat a b c}} | Joins the arguments into one string |
{{slugify value}} | Acme Inc → acme-inc |
{{split value by="&"}} | Inserts a line break before each occurrence of by |
{{markdown value}} | Renders markdown – useful for AI summaries and free-text fields |
{{date value format="MMM yyyy"}} | Formats a date; omit format for the default |
{{period months}} | 27 → 2 years, 3 months – for holding periods |
Numbers
| Helper | Result |
|---|---|
{{int value}} | Whole number with thousands separators |
{{round value 2}} | Fixed decimals |
{{number value decimals=1 prefix="" suffix=""}} | Formatted number with optional prefix and suffix |
{{short value}} | Abbreviated: 1234567 → 1.2m |
{{percentage value decimals=1}} | Multiplies by 100 and appends % – pass 0.152, get 15.2% |
{{currency value currency="EUR" decimals=0}} | Currency code plus an abbreviated amount |
{{growth "investment.fmv" decimals=1}} | Change against the previous period, styled up or down |
{{add a b}} {{mul a b}} {{div a b}} | Arithmetic |
{{currency}} and {{number}} understand Fundra's currency objects: passing a field that carries { value, currency } uses its own currency rather than the one you specify. {{growth}} takes a path as a string and compares the current record against the previous period's, so it works inside a repeated company card without extra plumbing.
Charts and visuals
{{chart}}
An area or bar chart over a series of rows – typically a company's timeseries.
| Option | Default |
|---|---|
metrics (or keys, dataKeys) | Inferred from the numeric columns present |
metricLabels | The metric names |
chartType (or variant) | area; use bar for bars |
xKey | period_label if present, else date |
stacked | true for bar charts, false for area |
colors | Built-in palette |
width / height | 640 / 280 |
legend | Shown when there's more than one series |
showValues | true |
valueDecimals | 0 |
yoy | false – overlays the prior-year series |
axes | One shared axis |
Lists are comma-separated. A metric can carry a fallback with or(...), so metrics="or(billedArr,revenue)" uses ARR where a company reports it and revenue where it doesn't – handy when one template covers a whole portfolio.
Other visual helpers
| Helper | Renders |
|---|---|
{{sparkline metric="investment_valuation"}} | An inline sparkline from the record's timeseries |
{{piechart data=segments min=0.05 other=true}} | A donut chart; slices below min roll into "Other" |
{{captable}} | The company's cap table as a donut, by ownership |
{{datagrid rows=... columns=...}} | A full data grid – grouping, aggregation, formatting |
{{portfolio}} | The standard portfolio overview table for the fund |
{{icon value}} | A colour chip derived from the value, plus its label |
{{flag "Germany"}} | Country flag and name |
{{avatar user}} | Avatar image; accepts a user object or a URL |
{{link value prefix="" name="" class=""}} | An anchor, adding https:// when missing |
{{#background}}…{{/background}} | Wraps content as a full-bleed page background |
Logic and arrays
| Helper | Behaviour |
|---|---|
{{eq a b}} {{neq a b}} | Equality, for use inside {{#if}} |
{{#lt a b}}…{{else}}…{{/lt}} | Block form of less-than |
{{or a b empty="–"}} | First truthy value, with a fallback |
{{nullif value}} | Turns falsy values into nothing, so {{#if}} treats 0 as absent |
{{get obj "a.b.c"}} | Reads a nested path |
{{#each (filter companies "investment_status" "active")}} | Filters by field; operator="eq" (default), "neq" or "in" |
{{#limit companies 5}}…{{/limit}} | Iterates the last n items |
{{#join tags separator=", "}}…{{/join}} | Joins an array, with an optional limit |
{{maxkey rows "fmv"}} | Largest value of a key across rows – useful for scaling bars |
{{count_by companies "country"}} | Counts grouped by a field |
{{percent_by_array companies "segment" by="fmv"}} | Shares by group, by count or weighted by a field – feeds {{piechart}} |
Partials
| Partial | Inserts |
|---|---|
{{> pagenumber}} | The current page number, filled in at print time |
{{> executive_summary}} | The executive summary written for this report |
You can define your own partials in a template and reuse them across sections – a company header, a KPI row, a footer block.
Putting it together
Because the output is HTML, your brand system carries straight over – the same fonts, colours and spacing scale as your website, applied with Tailwind classes. Custom CSS can be added per template for anything Tailwind doesn't cover, including print-specific rules like page breaks.