Connect FlutterFlow to TYPO3 via a FlutterFlow API Group calling a JSON endpoint that a TYPO3 developer must first enable — TYPO3's core has no built-in REST API. Install EXT:headless (or EXT:rest) on the TYPO3 side, verify JSON returns in a browser, then create an API Group in FlutterFlow with an Accept and Authorization header to pull content into your app.
| Fact | Value |
|---|---|
| Tool | TYPO3 |
| Category | DevOps & Tools |
| Method | FlutterFlow API Call |
| Difficulty | Intermediate |
| Time required | 60 minutes |
| Last updated | July 2026 |
TYPO3 as a Headless CMS for a FlutterFlow App
TYPO3 is a powerful enterprise CMS, but it was built as a traditional server-rendered system — its core does not expose a REST API. If you want to feed a FlutterFlow mobile or web app with TYPO3 content, a TYPO3 developer must first install and configure an extension that adds JSON output. The two most common choices are **EXT:headless** (the community standard for headless TYPO3, maintained by TYPO3 GmbH and the community) and **EXT:rest** (an alternative for custom Extbase-based REST). A custom Extbase controller is also an option for teams with specific needs. This prerequisite lives entirely on the TYPO3 server — there is nothing to configure in FlutterFlow until a browser request to the TYPO3 JSON endpoint returns a valid JSON response.
Once the JSON endpoint is live, FlutterFlow treats TYPO3 like any other REST API: an API Group with a base URL, an Accept header, and an authentication credential (JWT Bearer token or Basic Auth, depending on how the extension is configured). The integration is read-mostly — pulling pages, content elements, news records, or navigation trees into the Flutter app. TYPO3 is free and open-source; enterprise support and long-term support (LTS) releases are available through TYPO3 GmbH at paid tiers.
Two TYPO3-specific quirks affect the FlutterFlow setup. First, TYPO3's response envelopes differ between extensions — EXT:headless structures responses differently from EXT:rest or a custom controller. Always JSON-Path against your actual test response rather than assuming a particular field shape. Second, TYPO3 stores timestamps as Unix epoch integers in the `tstamp` field (not ISO 8601 strings), which means you need a Custom Function in FlutterFlow to convert epoch integers to human-readable dates. Both quirks are covered in the steps below.
Integration method
FlutterFlow connects to TYPO3 through a REST API endpoint that a TYPO3 developer must expose using an extension such as EXT:headless or EXT:rest — TYPO3 core does not include a REST API out of the box. Once the JSON endpoint is live and verified in a browser, FlutterFlow creates an API Group pointing at the endpoint, adds an Accept header and authentication credential, and uses JSON Path to extract nested TYPO3 content elements into widgets.
Prerequisites
- A TYPO3 instance with EXT:headless, EXT:rest, or a custom Extbase JSON controller installed and configured by a TYPO3 developer — confirm by opening the endpoint URL in a browser and seeing valid JSON
- A read-only API user credential for the TYPO3 JSON endpoint (JWT token or Basic Auth username/password, as configured by the extension)
- The full base URL of the TYPO3 JSON endpoint (e.g., https://your-typo3-site.com/api/ — the exact path depends on the extension configuration)
- A FlutterFlow account (any plan — API Calls work on all plans)
- Basic familiarity with FlutterFlow's API Calls panel and JSON Path syntax
Step-by-step guide
Verify the TYPO3 JSON endpoint before touching FlutterFlow
This step happens entirely outside FlutterFlow, and it is the single most important prerequisite. TYPO3 core does not expose a REST API — if a developer has not installed and configured a headless extension, there is literally nothing for FlutterFlow to call. Before you open FlutterFlow, verify the endpoint in your browser or a REST client like Hoppscotch (a free browser-based API tester). Open the endpoint URL in your browser — something like `https://your-typo3-site.com/?type=834` (EXT:headless default) or `https://your-typo3-site.com/api/pages` (custom setup). You should see a JSON response. If you see HTML (your TYPO3 site's normal output), the extension is either not installed or not configured. If you see a 403 or 401, the endpoint exists but requires authentication credentials. If the endpoint is not yet live, ask your TYPO3 developer to install **EXT:headless** (available in the TYPO3 Extension Repository, search 'headless' at extensions.typo3.org) and configure it to output pages and content elements as JSON. EXT:headless is the community-standard choice — it maps TYPO3's page tree and content elements (tt_content) to a JSON response and supports multiple JSON types (news, pages, breadcrumb, navigation). Once you can paste the URL in a browser and get JSON back, you are ready for FlutterFlow. Save the example JSON response — you'll paste it into FlutterFlow's Response & Test tab to generate JSON Paths automatically.
Pro tip: Ask your TYPO3 developer to create a read-only API user account with limited access — ideally one that can only read published content elements and pages. Never use admin credentials in FlutterFlow.
Expected result: Opening the TYPO3 JSON endpoint URL in a browser returns a valid JSON response (not HTML, not a 500 error) with your content data visible.
Create the TYPO3 API Group in FlutterFlow
With a confirmed working JSON endpoint, open FlutterFlow and click API Calls in the left navigation panel. Click + Add → Create API Group. Configure it: - **Group Name:** `TYPO3` - **Base URL:** The root of your TYPO3 JSON endpoint, e.g., `https://your-typo3-site.com/api/` or `https://your-typo3-site.com/` In the Headers section, click + Add Header for each required header: **Header 1:** `Accept` → `application/json` This tells the TYPO3 server (and any proxy in front of it) that you expect JSON, not HTML. **Header 2 (if JWT auth):** `Authorization` → `Bearer [App Constant: TYPO3_JWT]` Store the JWT in an App Constant: Settings & Integrations → App Settings → App Constants → add constant `TYPO3_JWT`. **Header 2 alternative (if Basic Auth):** `Authorization` → `Basic [base64(username:password)]` You can compute the Base64 value once (there are free online tools) and store it as an App Constant. Basic Auth credentials should be for a limited read-only API user, not a TYPO3 admin account. Note: the exact auth mechanism depends on how the TYPO3 developer configured the extension. Ask them which authentication method the endpoint expects before configuring the header. Click Save on the API Group.
1{2 "api_group_name": "TYPO3",3 "base_url": "https://your-typo3-site.com/api/",4 "headers": [5 {6 "name": "Accept",7 "value": "application/json"8 },9 {10 "name": "Authorization",11 "value": "Bearer [App Constant: TYPO3_JWT]"12 }13 ]14}Pro tip: If the TYPO3 server uses a self-signed SSL certificate (common in development or on-premise installs), FlutterFlow's built-in HTTPS client will reject it. Ask the TYPO3 admin to install a valid certificate (Let's Encrypt is free) before testing.
Expected result: The TYPO3 API Group appears in the API Calls panel with the base URL, Accept header, and Authorization header configured.
Add a GET Pages API Call and extract content with JSON Path
Inside the TYPO3 API Group, click + Add API Call. Set: - **Call Name:** `GetPages` - **Method:** GET - **Endpoint (relative):** Leave blank or set to the pages path as configured by your extension (e.g., `pages` or `?type=834&L=0`) For EXT:headless, the content structure wraps page and content data in a nested envelope. Add any required variables — for example, a `pageId` variable passed as a query parameter: in the Variables tab, add variable `pageId` (type Integer), then reference it in the endpoint as `?id=[pageId]`. In the Response & Test tab, paste your saved example JSON response into the Mock Response field (or click Test to fire a live request if your endpoint is public). FlutterFlow will offer to auto-generate JSON Paths from the response structure — click Generate. Then verify and add the paths you need: - `page_title` → `$.page.title` (EXT:headless structure) or `$.data[0].title` (varies by extension) - `page_uid` → `$.page.uid` - `content_elements` → `$.content.colPos0` (EXT:headless nests content by column position) - `element_header` → `$.content.colPos0[*].content.header` - `element_bodytext` → `$.content.colPos0[*].content.bodytext` - `last_changed` → `$.page.lastUpdated` (Unix epoch integer — see next step for conversion) The exact JSON Path depends entirely on which TYPO3 extension is installed and how it structures its response. Always test against your actual response — don't assume a path shape from documentation examples, because EXT:headless and EXT:rest produce different envelopes.
1{2 "call_name": "GetPages",3 "method": "GET",4 "endpoint": "?type=834&id=[pageId]&L=[language]",5 "variables": [6 { "name": "pageId", "type": "Integer", "default": "1" },7 { "name": "language", "type": "Integer", "default": "0" }8 ],9 "json_paths": [10 { "name": "page_title", "path": "$.page.title" },11 { "name": "page_uid", "path": "$.page.uid" },12 { "name": "content_col0", "path": "$.content.colPos0" },13 { "name": "element_header", "path": "$.content.colPos0[*].content.header" },14 { "name": "element_bodytext", "path": "$.content.colPos0[*].content.bodytext" },15 { "name": "last_updated", "path": "$.page.lastUpdated" }16 ]17}Pro tip: If your API Call test returns an empty response or unexpected HTML, check whether the endpoint requires a specific 'type' parameter (like '?type=834' for EXT:headless) or a specific HTTP Accept header value like 'application/json'. Ask the TYPO3 developer for the exact call format.
Expected result: The GetPages API Call returns a 200 response with JSON content, and JSON Path extractions correctly surface page titles, UIDs, and content element headers.
Convert TYPO3 epoch timestamps with a Custom Function
TYPO3 stores all timestamps — page creation date, last modification time, content element date — as Unix epoch integers in fields like `tstamp`, `crdate`, and `lastUpdated`. For example, a value of `1720396800` represents a point in time that your app needs to display as a human-readable string like 'July 8, 2024'. FlutterFlow's Text widgets cannot convert an integer to a date string directly in a binding expression. You need a Custom Function for this conversion. In FlutterFlow, go to Custom Code in the left nav → + Add → Function. Name it `epochToReadableDate`. In the function editor: 1. Set the return type to `String` 2. Add one argument: `epochSeconds` of type `int` 3. Paste the Dart code below into the function body After saving the function, go back to any Text widget that should show a date. In the Value binding field, instead of binding directly to the `last_updated` JSON Path value, click Set from Function → select `epochToReadableDate` → pass the `last_updated` JSON value (cast to int) as the argument. The widget will now display a formatted date string. Note: Custom Functions run in both Test mode and on device — unlike Custom Actions, they don't require an APK build to verify. You can see the result immediately in FlutterFlow's canvas.
1// FlutterFlow Custom Function: convert TYPO3 epoch to readable date2// In FlutterFlow: Custom Code → + Add → Function3import 'package:intl/intl.dart';45String epochToReadableDate(int epochSeconds) {6 if (epochSeconds == 0) return '';7 final dateTime = DateTime.fromMillisecondsSinceEpoch(8 epochSeconds * 1000,9 isUtc: true,10 ).toLocal();11 return DateFormat('MMM d, yyyy').format(dateTime);12}Pro tip: TYPO3 epoch values are in seconds (not milliseconds). Dart's DateTime.fromMillisecondsSinceEpoch expects milliseconds, so always multiply by 1000 when converting — the code above does this automatically.
Expected result: TYPO3 timestamp integers (e.g., 1720396800) display as human-readable date strings (e.g., 'Jul 8, 2024') in your FlutterFlow app's Text widgets.
Bind TYPO3 content to widgets and handle CORS for web builds
With API Calls and JSON Paths configured, bind the content to your FlutterFlow UI. Add a ListView to your screen → open its Backend Query panel → select the TYPO3 API Group and GetPages call. Inside the ListView, add a Column with Text widgets: - Bind the first Text widget to `element_header` (article or content element title) - Bind the second to `element_bodytext` (body text — note that TYPO3 bodytext fields often contain HTML markup from the rich text editor; use FlutterFlow's HTML widget or a `flutter_html` Custom Widget to render it properly) - Bind the date Text widget through the `epochToReadableDate` Custom Function applied to the `last_updated` value For write operations — submitting forms, approval workflows, publishing content — the TYPO3 extension may expose PATCH or POST endpoints. Treat any credential that has write access to TYPO3 as secret: route those calls through a Firebase Cloud Function or your own backend, never directly from FlutterFlow. **CORS for web builds:** If you publish your FlutterFlow app to the web (FlutterFlow's web publishing or Flutter web export), browser CORS restrictions apply. A web-published FlutterFlow app running in a browser will make cross-origin requests to your TYPO3 server. If the TYPO3 server doesn't respond with `Access-Control-Allow-Origin: *` (or your specific origin), the browser will block the request with an XMLHttpRequest error even though the API Call works fine in FlutterFlow's native mobile preview. Ask your TYPO3 administrator to configure CORS headers on the server — this is typically done at the nginx/Apache level or within the TYPO3 extension's middleware. Native iOS and Android builds are not affected by CORS. If you'd rather have a team configure the TYPO3-to-FlutterFlow pipeline, RapidDev sets up FlutterFlow integrations like this every week — free scoping call at rapidevelopers.com/contact.
Pro tip: TYPO3 bodytext fields from the rich text editor contain HTML entities and tags (like <p>, <strong>, <ul>). Render them using FlutterFlow's HTML widget (available in the widget picker) rather than a plain Text widget, which will show the raw HTML tags.
Expected result: TYPO3 content elements (headers, body text, dates) display correctly in your FlutterFlow app's ListView, with timestamps shown as readable dates and HTML content rendered by an HTML widget.
Common use cases
Corporate news and announcements app powered by TYPO3
A large enterprise uses TYPO3 as its central intranet CMS. Their IT team builds a FlutterFlow mobile app so employees can browse news articles, HR announcements, and policy updates from their phones. A TYPO3 developer installs EXT:headless and creates a read-only API user. FlutterFlow pulls the news list from the TYPO3 JSON endpoint and displays articles with titles, publication dates (converted from epoch), and body text.
Build a news feed screen that fetches articles from a TYPO3 EXT:headless endpoint at https://our-intranet.com/api/news, displays article title and published date (formatted from a Unix timestamp), and opens the full article body in a detail screen when tapped.
Copy this prompt to try it in FlutterFlow
Multilingual content delivery app from a TYPO3 backend
A European retailer manages product descriptions in 12 languages using TYPO3's powerful localization engine. A FlutterFlow app for their sales team displays product content in the rep's device language. The TYPO3 EXT:headless endpoint accepts a language parameter and returns localized content elements. FlutterFlow passes the device locale as a variable to the API Call and displays the localized fields.
Create a product detail screen that calls the TYPO3 JSON endpoint with a 'language' variable matching the device locale, and displays the localized product name, description, and feature list. Fall back to English if the device locale is not available.
Copy this prompt to try it in FlutterFlow
Event calendar app pulling TYPO3 calendar extension data
A university uses TYPO3 with a calendar extension to manage campus events. Their mobile app for students is built in FlutterFlow and calls the TYPO3 JSON endpoint to fetch upcoming events. Each event has a title, start timestamp (tstamp), location, and description stored in tt_content records. A FlutterFlow Custom Function converts the epoch timestamps to formatted date strings for display in a calendar list view.
Build an events screen that fetches upcoming campus events from a TYPO3 JSON API, converts the 'startTimestamp' Unix epoch integer to a readable date string like 'Jul 15, 2026', and displays events sorted by date in a ListView.
Copy this prompt to try it in FlutterFlow
Troubleshooting
API Call returns HTML (the TYPO3 website) instead of JSON
Cause: The TYPO3 headless extension is either not installed, not activated for the page tree you're querying, or the correct 'type' parameter is missing from the request URL.
Solution: Ask your TYPO3 developer to confirm the extension is installed and the correct URL pattern for JSON output (e.g., '?type=834' for EXT:headless). Verify the endpoint returns JSON in a browser before testing in FlutterFlow. If you're calling a wrong page UID that doesn't have the headless extension active, try a known-good page UID.
JSON Path returns null or empty even though the API Call returns a 200 response
Cause: Different TYPO3 extensions (EXT:headless vs EXT:rest vs custom Extbase) produce different JSON response envelopes. A JSON Path written for one extension's structure won't work for another.
Solution: In the API Call's Response & Test tab, paste your actual API response and use FlutterFlow's 'Generate JSON Paths' feature to auto-detect the real structure. Then manually verify each path against the raw JSON. Never assume a field path from documentation — always JSON-Path against your own test response.
XMLHttpRequest error in FlutterFlow web preview or published web app
Cause: The TYPO3 server is not sending CORS headers (Access-Control-Allow-Origin) in its response, so the browser blocks the cross-origin request. This only affects web builds; native iOS/Android builds are unaffected.
Solution: Ask your TYPO3 administrator to add CORS headers to the server configuration (nginx: add_header Access-Control-Allow-Origin '*'; or Apache: Header set Access-Control-Allow-Origin '*'). Alternatively, set a specific origin matching your FlutterFlow web app's domain. For native mobile-only apps, this issue doesn't arise.
Date fields display as large integer numbers instead of readable dates
Cause: TYPO3 stores timestamps as Unix epoch integers (seconds since Jan 1, 1970). FlutterFlow's Text widget binding shows the raw integer when no conversion is applied.
Solution: Create a FlutterFlow Custom Function named 'epochToReadableDate' (see Step 4) that converts the epoch integer to a formatted date string using Dart's DateTime and intl package. Bind date Text widgets through this function rather than directly to the raw JSON Path value.
401 Unauthorized or 403 Forbidden when calling the TYPO3 endpoint
Cause: The Authorization header is missing, the JWT has expired, or the credentials don't have access to the requested page tree or content.
Solution: Verify the Authorization header in the API Group is correctly set (Bearer for JWT, or Basic for username/password). If using JWT, check whether the token has expired — TYPO3 JWTs typically have a short lifetime and need to be refreshed. Ask the TYPO3 developer whether the endpoint requires credentials and what the correct auth format is for the specific extension installed.
Best practices
- Always verify the TYPO3 JSON endpoint returns valid JSON in a browser before touching FlutterFlow — there is no FlutterFlow-side fix for a TYPO3 that hasn't exposed a REST API yet.
- Create a dedicated read-only TYPO3 API user for FlutterFlow access; never use admin credentials or a user with edit/publish permissions in the API Group header.
- Store the JWT or Basic Auth credential as a FlutterFlow App Constant (Settings & Integrations → App Settings → App Constants), not as a raw string in the API Call header field.
- Always JSON-Path against your actual test response — never assume field names from documentation, because EXT:headless, EXT:rest, and custom controllers produce different envelope structures.
- Use FlutterFlow's HTML widget (not a plain Text widget) for TYPO3 bodytext fields that contain rich text editor output, which typically includes HTML tags and entities.
- Convert TYPO3 Unix epoch timestamps (tstamp, crdate, lastUpdated) to readable dates using a Custom Function — these are integer seconds, not ISO strings.
- For web-published FlutterFlow apps, ensure the TYPO3 server sends CORS headers; for mobile-only apps, CORS is not an issue.
- Treat any write-capable TYPO3 credentials as secret and route editorial or publishing API calls through a backend proxy — never embed write credentials in a compiled Flutter binary.
Alternatives
Choose WordPress over TYPO3 if your content team is less technical — WordPress has a built-in REST API at /wp-json/wp/v2/ that requires no extension or developer setup before FlutterFlow can call it.
Use GitHub as a content source if your content is Markdown files stored in a repository — FlutterFlow can fetch raw file content from the GitHub API without any CMS setup.
Consider ManageEngine instead of TYPO3 if your goal is IT service management and ticketing rather than website content delivery — both require product-specific API setup but serve entirely different purposes.
Frequently asked questions
Does TYPO3 have a built-in REST API I can call from FlutterFlow?
No — TYPO3 core does not include a REST API. To expose JSON from TYPO3, a developer must install an extension: EXT:headless is the most widely used community standard, EXT:rest is an alternative, and custom Extbase controllers are an option for teams with specific data requirements. This is the single biggest prerequisite for the integration — FlutterFlow has nothing to call until the TYPO3 side exposes JSON.
Can non-technical founders set up the TYPO3 side of this integration themselves?
Generally not — installing TYPO3 extensions, configuring their routing, and setting up API authentication requires access to the TYPO3 backend and familiarity with TYPO3's extension management. This is a developer task. However, once a developer has the endpoint live and hands you the URL and credentials, the FlutterFlow side (API Group, JSON Paths, widget bindings) is fully visual and beginner-friendly.
Why do TYPO3 timestamps show as large numbers in my app?
TYPO3 stores all modification and creation dates as Unix epoch integers (seconds since January 1, 1970) rather than ISO 8601 date strings. A FlutterFlow Text widget binding shows the raw integer (e.g., 1720396800) without conversion. You need to add a Custom Function in FlutterFlow that multiplies the integer by 1000 and passes it to Dart's DateTime.fromMillisecondsSinceEpoch, then formats the result with the intl package. Step 4 in this guide provides the exact Dart code.
Will my FlutterFlow app work as a web app calling TYPO3?
It depends on whether the TYPO3 server sends CORS headers. Native iOS and Android builds make HTTP requests directly from the device — browser CORS restrictions don't apply. But if you publish your FlutterFlow app to the web, the browser enforces same-origin policy and will block requests to your TYPO3 server unless it responds with an Access-Control-Allow-Origin header. Ask your TYPO3 administrator to configure CORS at the server level (nginx or Apache configuration) before relying on web publishing.
Can I write content back to TYPO3 from FlutterFlow (editing, publishing)?
Some TYPO3 headless extensions do expose write endpoints (PATCH, POST) for updating records or triggering publishing workflows. If your integration needs this, configure a backend proxy (Firebase Cloud Function or your own server) to hold the write-capable credentials and make the TYPO3 write calls. Never place credentials that can edit or publish TYPO3 content inside a FlutterFlow App Constant — they are compiled into the app binary and extractable.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation