Skip to main content
RapidDev - Software Development Agency
lovable-integrationsEdge Function Integration

How to Integrate Lovable with TYPO3

Connect your Lovable app to a TYPO3 CMS installation by calling the TYPO3 Headless Extension REST API from a Supabase Edge Function. Fetch content elements, pages, news, and custom records in JSON format. TYPO3 is the enterprise CMS of choice in the DACH region and across European public sector and corporate websites, unlike WordPress which dominates globally.

What you'll learn

  • How to set up TYPO3's Headless Extension and configure it for JSON API access
  • How to fetch TYPO3 pages, content elements, and navigation via Edge Function
  • How to handle TYPO3's TypoScript-based content element types in your React frontend
  • How to integrate TYPO3 news records and custom extensions via the headless API
  • How TYPO3's enterprise features differ from WordPress for European corporate websites
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate12 min read40 minutesCMSMarch 2026RapidDev Engineering Team
TL;DR

Connect your Lovable app to a TYPO3 CMS installation by calling the TYPO3 Headless Extension REST API from a Supabase Edge Function. Fetch content elements, pages, news, and custom records in JSON format. TYPO3 is the enterprise CMS of choice in the DACH region and across European public sector and corporate websites, unlike WordPress which dominates globally.

Build a headless TYPO3 frontend with Lovable and the TYPO3 JSON API

TYPO3 is the enterprise CMS that dominates the DACH region (Germany, Austria, Switzerland) and is widely used across European government, higher education, and corporate websites. While less known globally than WordPress, TYPO3 powers a significant portion of the European enterprise web — including many organizations that cannot easily migrate to newer headless-first platforms due to content complexity, multilingual requirements, or organizational constraints.

The TYPO3 Headless Extension (available at extensions.typo3.org as 'headless' by macopedia) transforms any TYPO3 installation into a headless CMS by exposing its page tree and content elements as JSON via REST API endpoints. Content editors continue working in the familiar TYPO3 backend, and the Lovable frontend consumes the structured JSON. The extension supports TYPO3's full content model — text elements, image blocks, grids, fluid templates, news (tt_news/ext:news), and custom record types.

For organizations running TYPO3 in production and considering a frontend modernization, the headless extension provides the lowest-friction migration path: no content migration, no CMS change, no editor retraining. The Lovable app replaces only the TYPO3 frontend rendering layer. This tutorial covers the EXT:headless extension approach, which is the current standard for TYPO3 headless development as of TYPO3 v12 and v13.

Integration method

Edge Function Integration

TYPO3 integrates with Lovable through a Supabase Edge Function that calls the TYPO3 Headless Extension's JSON API endpoints. The TYPO3 site URL is stored in Cloud → Secrets. The Edge Function fetches page content, navigation trees, and custom content types from TYPO3's headless API and returns structured JSON to the React frontend. Authentication for restricted content uses TYPO3's built-in API key or frontend user login via the headless extension's auth endpoints.

Prerequisites

  • A TYPO3 installation (version 10 LTS or higher recommended) with the EXT:headless extension installed and configured
  • The TYPO3 Headless Extension (composer require friendsoftypo3/headless or install from TYPO3 Extension Repository)
  • Your TYPO3 site's API base URL (configured in the headless extension's site configuration)
  • A Lovable account with an active Lovable Cloud project

Step-by-step guide

1

Set up TYPO3 Headless Extension and store the site URL

The TYPO3 Headless Extension must be installed and configured on your TYPO3 server before you can call its API. If your TYPO3 administrator has not yet set this up, the installation steps are: install via Composer (composer require friendsoftypo3/headless), activate the extension in TYPO3 Extension Manager, and configure the site's headless mode in the TYPO3 Site Configuration (each Site Configuration file at config/sites/{site}/config.yaml needs headless: true added). Once installed, the TYPO3 Headless Extension exposes API endpoints under your TYPO3 installation's domain. The main endpoint for page content is: GET https://your-typo3-site.com/?type=834 (the 834 page type is the headless content type registered by the extension). For navigation, it is ?type=835. These are query-parameter based endpoints for compatibility with all TYPO3 URL configurations. Alternatively, with clean URL configuration, the endpoints can be path-based like https://your-typo3-site.com/api/page and https://your-typo3-site.com/api/navigation. The exact URL format depends on your TYPO3 site's TypoScript configuration. In Lovable, click '+' next to Preview to open the Cloud panel, then click 'Secrets'. Add: - TYPO3_SITE_URL — your TYPO3 installation base URL (e.g., https://www.yoursite.com) - TYPO3_API_KEY — an API key if your TYPO3 headless setup requires authentication (optional, depends on configuration) Verify the setup by visiting https://your-typo3-site.com/?type=834&slug=/ in a browser — it should return a JSON object with page and content data.

Pro tip: Ask your TYPO3 developer or administrator to test the headless endpoint URL manually and share the exact URL format and response structure with you. TYPO3 headless configurations vary significantly based on site configuration and TypoScript setup.

Expected result: Visiting {TYPO3_SITE_URL}/?type=834 in a browser returns a JSON response with a 'page' object and 'content' array. The headless extension is confirmed working.

2

Create the TYPO3 headless API proxy Edge Function

The Edge Function proxies requests to TYPO3's headless API, handling CORS (TYPO3 is on a different domain from the Lovable frontend) and adding any required authentication headers. The function accepts parameters for the page slug (or UID) and language ID, constructs the TYPO3 API URL, fetches the JSON response, and returns it to the frontend. TYPO3's headless API response structure differs from WordPress. The response contains a 'page' object with page metadata and a 'content' object with colPos-keyed content element arrays. Content elements have a 'component' field (matching the CType) and 'data' field with the content. Your React components need to handle each content element type (header, text, textpic, image, bullets, table, media, etc.) based on the component type. The navigation endpoint (?type=835) returns the full page tree in a nested format useful for building navigation menus, breadcrumbs, and sitemaps. Cache the navigation response as it changes rarely. The slug parameter maps to TYPO3 page slugs configured in the URL Routing of your TYPO3 site. If your TYPO3 site uses the older uid-based URL system, pass the page UID as the 'id' parameter instead.

Lovable Prompt

Create a Supabase Edge Function at supabase/functions/typo3-proxy/index.ts that proxies requests to a TYPO3 Headless Extension API. Read TYPO3_SITE_URL and TYPO3_API_KEY (optional) from Deno.env.get(). Accept a POST request with 'slug' string (page path), 'lang' integer (language UID, defaults to 0), and 'type' integer (834 for content, 835 for navigation). Build the TYPO3 API URL with these parameters. If TYPO3_API_KEY exists, add it as an X-Api-Key header. Return the TYPO3 JSON response with CORS headers.

Paste this in Lovable chat

supabase/functions/typo3-proxy/index.ts
1// supabase/functions/typo3-proxy/index.ts
2const corsHeaders = {
3 'Access-Control-Allow-Origin': '*',
4 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
5};
6
7Deno.serve(async (req) => {
8 if (req.method === 'OPTIONS') return new Response('ok', { headers: corsHeaders });
9
10 try {
11 const { slug = '/', lang = 0, type = 834 } = await req.json() as {
12 slug?: string; lang?: number; type?: number;
13 };
14
15 const siteUrl = Deno.env.get('TYPO3_SITE_URL')!.replace(/\/$/, '');
16 const apiKey = Deno.env.get('TYPO3_API_KEY');
17
18 // Build TYPO3 headless API URL
19 const params = new URLSearchParams({
20 type: String(type),
21 slug: slug.startsWith('/') ? slug : `/${slug}`,
22 L: String(lang),
23 });
24
25 const url = `${siteUrl}/?${params.toString()}`;
26 const headers: Record<string, string> = { 'Accept': 'application/json' };
27 if (apiKey) headers['X-Api-Key'] = apiKey;
28
29 console.log(`Fetching TYPO3 API: ${url}`);
30 const typo3Response = await fetch(url, { headers });
31
32 if (!typo3Response.ok) {
33 console.error(`TYPO3 API error ${typo3Response.status} for slug: ${slug}`);
34 return new Response(JSON.stringify({ error: `TYPO3 API returned ${typo3Response.status}` }), {
35 status: typo3Response.status,
36 headers: { ...corsHeaders, 'Content-Type': 'application/json' },
37 });
38 }
39
40 const data = await typo3Response.json();
41 return new Response(JSON.stringify(data), {
42 headers: { ...corsHeaders, 'Content-Type': 'application/json' },
43 });
44 } catch (error) {
45 console.error('typo3-proxy error:', error);
46 return new Response(JSON.stringify({ error: String(error) }), {
47 status: 500,
48 headers: { ...corsHeaders, 'Content-Type': 'application/json' },
49 });
50 }
51});

Pro tip: Cache the navigation response (type=835) in Supabase with a 1-hour TTL — the TYPO3 page tree changes infrequently and the navigation response is large. Fetching it on every page load adds unnecessary latency.

Expected result: The typo3-proxy Edge Function deploys and a test request with slug='/' returns the TYPO3 homepage content as JSON with page metadata and content element arrays.

3

Build the TYPO3 content element renderer

TYPO3 content elements come in many types (CTypes), and the headless extension maps each CType to a 'component' value in the JSON response. Your React frontend needs to handle each content type with an appropriate component. The most common TYPO3 content types you will encounter are: - header — headline with optional subheader and link. Data includes header, subheader, headerLayout (h1-h6), and link. - text — body text. Data includes bodytext (HTML string from RTE). - textpic — text with image. Data includes bodytext, imageorient (image position), and gallery with image data. - image — standalone images. Data includes gallery.rows with image objects. - bullets — unordered or ordered lists. Data includes bullets array. - table — HTML table. Data includes bodytext (HTML). - media — embedded video/audio. Data includes assets with file references. - menu_* — page menu variants for navigation components. The headless extension structures content in colPos groups — content assigned to different page column positions. colPos 0 is the main content area, colPos 1 is typically a sidebar. Your React components should map to the appropriate column. Ask Lovable to build a content renderer component that uses a switch statement on the component type to render different React components for each TYPO3 CType. Describe the content types used on your specific TYPO3 site.

Lovable Prompt

Build a TYPO3 content renderer component called Typo3ContentRenderer. It receives an array of content elements from the TYPO3 headless API response (content.colPos0 array). For each element, render based on element.component: 'header' → an h-tag component using element.data.header and element.data.subheader; 'text' → a div with element.data.bodytext rendered as HTML (sanitize with DOMPurify); 'textpic' → text and image side-by-side using the first image from element.data.gallery.rows; 'bullets' → a ul/ol list from element.data.bullets. For unknown component types, log the type and render a placeholder.

Paste this in Lovable chat

Pro tip: Log all unique 'component' values from your TYPO3 API responses to Cloud → Logs during development. TYPO3 installations often have custom content element types from third-party extensions — knowing all the types your site uses helps you build complete renderer coverage.

Expected result: The content renderer displays TYPO3 page content correctly for common element types. The main page renders with headlines, body text, and images from the TYPO3 CMS. Unknown content types show a fallback placeholder.

Common use cases

Render TYPO3 page content in a Lovable app

The TYPO3 backend contains thousands of existing pages structured in a page tree. The Lovable app maps TYPO3 page UIDs or slugs to routes, fetches the page's content elements via the headless API, and renders them in modern React components. Content editors continue creating and editing pages in the TYPO3 backend while the Lovable frontend provides the modern, fast user experience.

Lovable Prompt

Build a dynamic page renderer for a TYPO3 headless site. When users navigate to any route, call the typo3-proxy Edge Function with the page path to fetch content from TYPO3. Handle the following content element types from the response: header (CType=header), text (CType=text), textpic (CType=textpic with image), and bullets (CType=bullets). Render each into a matching React component. Show a 404 page if the TYPO3 API returns no content for the path.

Copy this prompt to try it in Lovable

Display TYPO3 News (EXT:news) with category filtering

Organizations using the popular EXT:news TYPO3 extension have structured news records with categories, tags, related articles, and author information. The headless extension exposes news records through a dedicated API endpoint. The Lovable app fetches news with pagination, supports category filtering, and renders individual news detail pages from the TYPO3 news records.

Lovable Prompt

Create a news listing page that fetches EXT:news records from TYPO3 via the typo3-proxy Edge Function. Call the TYPO3 news API endpoint with parameters for pagination and optional category filter. Display news items with: main image, headline, teaser text, category badges, author, and publish date. Add category filter chips at the top. Clicking a news item navigates to /news/:slug which fetches the full news detail from TYPO3.

Copy this prompt to try it in Lovable

Render TYPO3 multilingual content in the correct language

TYPO3 is strong at multilingual content management with built-in language layers for each page and content element. The headless API supports language selection via the L parameter or Accept-Language header. The Lovable app detects the user's browser language or URL-based language prefix, passes it to the Edge Function, and renders the correct TYPO3 language version for each page.

Lovable Prompt

Add multilingual support to the TYPO3 headless frontend. Detect the current language from the URL prefix (/de/, /en/, /fr/). Pass the corresponding TYPO3 language ID as an L parameter when calling the typo3-proxy Edge Function. Display a language switcher in the header that changes the URL prefix and refetches page content in the selected language. Store the user's language preference in localStorage.

Copy this prompt to try it in Lovable

Troubleshooting

TYPO3 API returns HTML page instead of JSON

Cause: The TYPO3 Headless Extension is not installed, not activated, or the type=834 page type is not registered. Without the headless extension, TYPO3 returns normal HTML responses for all requests.

Solution: Verify the EXT:headless extension is installed by checking the TYPO3 Extension Manager in the backend. Ask your TYPO3 administrator to confirm the extension is activated and the site configuration has headless: true. Test by visiting yoursite.com/?type=834 in a browser with incognito mode — it should return JSON, not HTML.

Edge Function returns 404 for all page slugs

Cause: The TYPO3 URL routing is not configured to pass the slug parameter to the headless API, or the page slug in the request does not match any page configured in TYPO3's URL routing.

Solution: Try fetching content by page UID instead of slug: change the URL parameter from 'slug' to 'id' and use the numeric TYPO3 page UID. Page UIDs are visible in the TYPO3 backend page tree (shown in brackets next to page names). If UID-based requests work but slug-based requests do not, your TYPO3 site's URL routing needs to be configured to support slug-based navigation in the headless mode.

Images in TYPO3 content elements have relative URLs that do not load

Cause: TYPO3 headless extension may return image URLs as relative paths (e.g., /fileadmin/images/photo.jpg) rather than absolute URLs.

Solution: Prepend TYPO3_SITE_URL to all relative image paths when processing the API response. Check each image URL in the gallery data: if it starts with '/', prepend the site URL. You can normalize this in the Edge Function before returning the response, or handle it client-side in the React image renderer component.

typescript
1// Normalize relative image URLs in Edge Function
2function normalizeImageUrls(data: unknown, siteUrl: string): unknown {
3 const str = JSON.stringify(data);
4 // Replace relative /fileadmin/ paths with absolute URLs
5 return JSON.parse(str.replace(/"\/fileadmin\//g, `"${siteUrl}/fileadmin/`));
6}

Best practices

  • Cache TYPO3 navigation data (type=835) in Supabase with a 1-hour TTL — navigation trees change rarely and are expensive to fetch on every page load.
  • Build a comprehensive content element renderer that handles all TYPO3 CTypes used on your specific site — log unknown component types to Cloud → Logs during development to identify custom elements from third-party extensions.
  • Normalize image URLs in the Edge Function by prepending TYPO3_SITE_URL to relative paths — TYPO3 often returns relative /fileadmin/ image paths that require the base URL to load correctly.
  • Use TYPO3's built-in language layers (L parameter) for multilingual sites rather than maintaining separate Lovable content — TYPO3's translation system is one of its strongest features and should be leveraged in the headless architecture.
  • Handle TYPO3 access-restricted pages gracefully — the headless API returns different HTTP status codes for pages requiring login, and the frontend should redirect to a login page rather than showing a broken content view.
  • Sanitize TYPO3 RTE (rich text editor) bodytext fields with DOMPurify before rendering with dangerouslySetInnerHTML — TYPO3 RTE content can contain arbitrary HTML.
  • Test with TYPO3's staging or acceptance environment before connecting to production — headless extension configuration changes can affect page rendering for all users and should be validated before production deployment.

Alternatives

Frequently asked questions

Which TYPO3 versions are supported by the Headless Extension?

The EXT:headless extension (headless by macopedia) supports TYPO3 v10 LTS, v11 LTS, v12 LTS, and v13. TYPO3 v9 and earlier require an older version of the extension with different API behavior. TYPO3 v12 and v13 are the recommended versions for new headless projects as they have the most complete headless support and receive active maintenance.

Can I use this integration with TYPO3 Fluid templates alongside the headless extension?

The headless extension replaces Fluid template rendering with JSON output — when a page is served via the headless API (type=834), Fluid templates are not used. For a mixed setup where some pages are still rendered by TYPO3 Fluid and others are served headlessly, configure specific page trees or site roots as headless while others remain traditional. Talk to your TYPO3 developer about a gradual migration approach.

How does TYPO3 handle multilingual content in the headless API?

Pass the TYPO3 language UID as the L parameter in the API request. Language UID 0 is always the default language. Additional languages configured in your TYPO3 installation have numeric UIDs (1, 2, 3, etc.) visible in the TYPO3 Site Configuration. The headless API returns the content in the requested language with fallback to the default language for untranslated elements.

Is TYPO3 still actively maintained in 2026?

Yes. TYPO3 is actively maintained by the TYPO3 Association with regular LTS (Long Term Support) releases every 1.5 years. TYPO3 v12 LTS was released in 2023 with support through 2026, and TYPO3 v13 LTS in 2024. The CMS has a strong European enterprise customer base and a dedicated open-source community. It is particularly dominant in the DACH region where many government, education, and corporate websites rely on it.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.