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

How to Integrate Lovable with Joomla

Connect your Lovable app to Joomla's built-in Web Services API (available since Joomla 4.0) by creating a Supabase Edge Function that authenticates with a Joomla API token and fetches articles, categories, menu items, and custom fields. Joomla is the right choice when your content management requires fine-grained ACL (Access Control List) and complex user group permissions, unlike WordPress which uses a simpler role-based system.

What you'll learn

  • How to enable the Joomla Web Services API plugin and generate an API token
  • How to write a Supabase Edge Function that fetches Joomla articles with authentication
  • How to query Joomla content by category, tag, language, and custom fields
  • How to handle Joomla's ACL-based access levels when fetching content
  • How Joomla's API compares to WordPress REST API for headless CMS architectures
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate12 min read30 minutesCMSMarch 2026RapidDev Engineering Team
TL;DR

Connect your Lovable app to Joomla's built-in Web Services API (available since Joomla 4.0) by creating a Supabase Edge Function that authenticates with a Joomla API token and fetches articles, categories, menu items, and custom fields. Joomla is the right choice when your content management requires fine-grained ACL (Access Control List) and complex user group permissions, unlike WordPress which uses a simpler role-based system.

Use Joomla as a headless CMS with its built-in Web Services API in Lovable

Joomla 4.0 introduced a fully built-in Web Services API (previously requiring third-party extensions), making it a first-class headless CMS option without additional plugins. The API follows JSON:API specification and exposes articles, categories, menu items, users, tags, modules, and custom fields through RESTful endpoints under /api/index.php/v1/. Authentication uses a Joomla API Token tied to a Super User account — a static Bearer token generated in the Joomla backend.

Joomla's primary differentiation from WordPress is its sophisticated Access Control List (ACL) system. Where WordPress has a handful of built-in roles (Administrator, Editor, Author, etc.), Joomla allows creating arbitrary user groups with granular permissions for viewing, editing, publishing, and deleting each content category. This makes Joomla particularly strong for community platforms, membership sites, and corporate intranets where different user groups need access to different content. In a headless Joomla setup, the API token determines what access level the API can retrieve — Super User tokens can access all content, while restricted tokens respect Joomla's ACL rules.

For developers building on top of existing Joomla sites, the Web Services API provides complete content access without requiring any theme or template changes. The existing Joomla frontend can continue serving the traditional site while the Lovable app consumes the same content through the API — a gradual modernization approach that is common in organizations with large Joomla installations they cannot migrate all at once.

Integration method

Edge Function Integration

Joomla's Web Services API integrates with Lovable through a Supabase Edge Function that authenticates using a Joomla API Token (generated in the Super User profile) and calls the Joomla v1 REST API endpoints. The Joomla site URL and API token are stored in Cloud → Secrets. The Edge Function fetches articles, categories, menus, and custom fields from Joomla and returns structured JSON to the React frontend.

Prerequisites

  • A Joomla 4.0 or newer installation (the Web Services API is built-in from Joomla 4.0; Joomla 3.x requires a third-party API plugin)
  • The Joomla 'API Authentication - Web Services' plugin enabled (Plugins → API Authentication → Web Services)
  • A Joomla API Token generated for a Super User account (Users → Manage → edit Super User → Joomla API Token tab)
  • Your Joomla site's base URL (e.g., https://www.yourjoomlasite.com)
  • A Lovable account with an active Lovable Cloud project

Step-by-step guide

1

Enable the Joomla API and generate an API token

Joomla 4.0+ includes the Web Services API built-in, but it requires a plugin to be enabled and an API token to be generated before it can be called. First, enable the API Authentication plugin: In your Joomla administrator, go to Extensions → Plugins. Search for 'API Authentication'. Find 'API Authentication - Web Services' and make sure its status is 'Enabled' (green checkmark). If it is disabled, click on it and change Status to Enabled, then save. Next, generate an API token for a Super User: Go to Users → Manage. Click on a Super User account (usually 'Super User' or your main admin account). In the user editing form, look for the 'Joomla API Token' tab on the right side (in Joomla 4) or the API Token section within the user form. Click 'Generate a new token'. Copy the generated token — it is shown once and looks like a long alphanumeric string. In Lovable, click '+' next to Preview to open the Cloud panel, then click 'Secrets'. Add: - JOOMLA_SITE_URL — your Joomla site's base URL (e.g., https://www.yoursite.com) - JOOMLA_API_TOKEN — the generated API token Verify the API is working by visiting https://www.yoursite.com/api/index.php/v1/articles in a browser (you will see an authorization error, confirming the endpoint exists and requires the token — that is correct behavior).

Pro tip: The Joomla API token is tied to a user account and respects that user's permissions. A Super User token can access all content and write to any resource. For read-only API access, create a separate Joomla user with only 'View' permissions and generate a token for that account.

Expected result: The API Authentication plugin shows as Enabled. A Joomla API token is generated and stored in Cloud → Secrets. A request to your-site.com/api/index.php/v1/articles with 'Authorization: Bearer {token}' returns the articles JSON.

2

Create the Joomla Web Services API proxy Edge Function

The Edge Function proxies requests to Joomla's /api/index.php/v1/ endpoints with the API token in the Authorization header. Joomla's API follows the JSON:API specification, which means responses are structured differently from WordPress — data is in a 'data' array with 'attributes' and 'relationships' objects rather than flat objects. Joomla API endpoints for common resources: - Articles: GET /api/index.php/v1/articles - Single article: GET /api/index.php/v1/articles/{id} - Categories: GET /api/index.php/v1/categories?component=com_content - Menus: GET /api/index.php/v1/menus - Menu items: GET /api/index.php/v1/menus/{menu-id}/items - Tags: GET /api/index.php/v1/tags Query parameters for articles: - filter[category_id]={id} — filter by category - filter[state]=1 — only published articles - page[offset]={n}&page[limit]={n} — pagination - sort=title — sort field - filter[search]={term} — text search The Edge Function accepts a 'path' parameter and proxies it to Joomla, making it reusable for any Joomla API endpoint.

Lovable Prompt

Create a Supabase Edge Function at supabase/functions/joomla-proxy/index.ts that proxies requests to the Joomla Web Services API. Read JOOMLA_SITE_URL and JOOMLA_API_TOKEN from Deno.env.get(). Accept a POST request with a 'path' string (e.g., '/articles?filter[state]=1&page[limit]=10'). Build the full Joomla API URL and call it with 'Authorization: Bearer {token}' header. Return the Joomla JSON:API response with CORS headers. Include error handling for 401 and 404 responses.

Paste this in Lovable chat

supabase/functions/joomla-proxy/index.ts
1// supabase/functions/joomla-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 { path } = await req.json() as { path: string };
12
13 if (!path) {
14 return new Response(JSON.stringify({ error: 'path is required (e.g., /articles?filter[state]=1)' }), {
15 status: 400,
16 headers: { ...corsHeaders, 'Content-Type': 'application/json' },
17 });
18 }
19
20 const siteUrl = Deno.env.get('JOOMLA_SITE_URL')!.replace(/\/$/, '');
21 const apiToken = Deno.env.get('JOOMLA_API_TOKEN')!;
22
23 const url = `${siteUrl}/api/index.php/v1${path.startsWith('/') ? path : '/' + path}`;
24
25 const joomlaResponse = await fetch(url, {
26 headers: {
27 'Authorization': `Bearer ${apiToken}`,
28 'Accept': 'application/vnd.api+json',
29 'Content-Type': 'application/vnd.api+json',
30 },
31 });
32
33 if (!joomlaResponse.ok) {
34 const errText = await joomlaResponse.text();
35 console.error(`Joomla API error ${joomlaResponse.status} for path: ${path}`);
36 return new Response(JSON.stringify({ error: `Joomla API returned ${joomlaResponse.status}`, detail: errText }), {
37 status: joomlaResponse.status,
38 headers: { ...corsHeaders, 'Content-Type': 'application/json' },
39 });
40 }
41
42 const data = await joomlaResponse.json();
43
44 // Joomla JSON:API response has data[] and links for pagination
45 return new Response(JSON.stringify({
46 data: data.data ?? data,
47 links: data.links ?? null,
48 meta: data.meta ?? null,
49 }), {
50 headers: { ...corsHeaders, 'Content-Type': 'application/json' },
51 });
52 } catch (error) {
53 console.error('joomla-proxy error:', error);
54 return new Response(JSON.stringify({ error: String(error) }), {
55 status: 500,
56 headers: { ...corsHeaders, 'Content-Type': 'application/json' },
57 });
58 }
59});

Pro tip: Joomla's JSON:API response uses 'data[].attributes' for content — map article.attributes.title, article.attributes.introtext, article.attributes.catid, etc. in your React components rather than accessing properties directly on the data item.

Expected result: The joomla-proxy Edge Function deploys. A test request with path '/articles?filter[state]=1&page[limit]=5' returns a JSON:API response with a 'data' array of published Joomla articles.

3

Build the articles listing and detail pages

With the Edge Function deployed, build the frontend components that display Joomla content. Joomla's JSON:API response structure requires some mapping before display — each article is at data[n].attributes, with fields like title, introtext, fulltext, catid, images (JSON-encoded image paths), publish_up (publish date), and metadesc. For article images: Joomla stores images as a JSON string in the 'images' field. Parse it to extract images.image_intro (the intro/list image URL) and images.image_fulltext (the article detail page image). Prepend JOOMLA_SITE_URL to these relative paths to construct absolute image URLs. For article body content: introtext contains the text shown in listings. fulltext contains the continuation after a Read More break. For article detail pages, combine introtext + fulltext and render as HTML (sanitize with DOMPurify). For pagination: Joomla's JSON:API pagination uses links.next and links.prev URL fields rather than page numbers — follow these links for next/previous page navigation, or parse the offset parameter from the links.next URL to build numbered pagination. Ask Lovable to build the article listing and detail pages using these field mappings:

Lovable Prompt

Build a Joomla articles page that calls the joomla-proxy Edge Function. Fetch articles with path '/articles?filter[state]=1&page[limit]=9&page[offset]=0&sort=-publish_up'. For each article in data[], display: the intro image (parse article.attributes.images as JSON, use images.image_intro prepended with site base URL), article.attributes.title as the card title, strip HTML from article.attributes.introtext for the preview text, and format article.attributes.publish_up as a date. Add a Load More button that fetches the next page by incrementing page[offset] by 9.

Paste this in Lovable chat

Pro tip: Joomla's introtext field often contains HTML from the WYSIWYG editor. Strip HTML tags for card previews but use dangerouslySetInnerHTML (with DOMPurify sanitization) for the full article detail view where rich formatting matters.

Expected result: The articles page loads Joomla content, displays articles with images and previews, and the Load More button fetches additional articles. Clicking an article shows the full content view with sanitized HTML.

Common use cases

Build a Lovable articles listing with Joomla category filtering

Your organization manages hundreds of articles in Joomla organized by category. The Lovable app fetches articles from the Joomla API with optional category filtering, displays them in a searchable and filterable listing, and links to full article detail pages. The Joomla editorial team continues publishing articles through the familiar Joomla admin backend.

Lovable Prompt

Build an articles page that fetches content from the joomla-proxy Edge Function. Call the Joomla API for articles with optional categoryId parameter. Display articles in a card grid with: article title, category badge, publication date, intro image (from Joomla's images.intro field), and intro text (strip HTML tags for plain text preview). Add a category dropdown filter that refetches articles by category. Implement pagination using the page and limit query parameters.

Copy this prompt to try it in Lovable

Display a Joomla menu structure as site navigation

Joomla manages the site's navigation structure through its menu system. The Lovable app fetches the main menu's items via the Joomla API and renders a responsive navigation menu. Menu items include the linked article or page, icon, and child items for dropdown navigation. This keeps navigation in sync with the Joomla backend without manual updates to the Lovable app.

Lovable Prompt

Create a navigation component that fetches the Joomla main menu via the joomla-proxy Edge Function. Call the API for menu items in the menu with id 1 (adjust for your Joomla menu ID). Build a responsive navigation bar with the menu items. For parent items with children, render a dropdown. For items linking to articles, construct the internal Lovable route (/articles/:id). Cache the menu in React state so it does not refetch on every navigation.

Copy this prompt to try it in Lovable

Sync Joomla custom fields data for product or resource listings

Joomla's custom fields extension allows attaching structured data to articles — product specifications, event dates, geographic coordinates, or resource attributes. The Joomla API exposes custom field values alongside article data. The Lovable app fetches articles in a specific category and uses custom field values to render structured product cards or resource listings.

Lovable Prompt

Build a product listing page that fetches Joomla articles from the 'Products' category. Each article has custom fields: price (text field), sku (text field), in_stock (checkbox). Display products as cards using the article title, intro image, and these custom field values. Show a green 'In Stock' or red 'Out of Stock' badge based on the in_stock custom field. Filter by price range using the min/max values from the custom fields.

Copy this prompt to try it in Lovable

Troubleshooting

Joomla API returns 401 'Not authenticated' for all requests

Cause: The API Authentication plugin is not enabled, the API token is invalid, or the Authorization header is malformed.

Solution: In Joomla admin, go to Extensions → Plugins, search for 'API Authentication', and verify the 'API Authentication - Web Services' plugin is enabled (green checkmark). Regenerate the API token in Users → Manage → Super User → Joomla API Token tab. Verify the JOOMLA_API_TOKEN secret in Cloud → Secrets matches the newly generated token exactly.

Joomla API returns 404 for /api/index.php/v1/articles

Cause: The Joomla Web Services API component is not installed or the api/index.php URL rewrite is blocked by .htaccess or server configuration.

Solution: Joomla 4.0+ includes the Web Services API as a core component. Verify your Joomla version is 4.0 or newer in Help → System Information. Also check that the com_api component is listed in the Extensions → Manage component list. Some hosting environments block the /api/ path — check with your host if the endpoint returns 404.

Images in articles have broken URLs (relative paths that do not load)

Cause: Joomla stores image paths as relative paths (e.g., /images/articles/photo.jpg) in the JSON. The frontend needs to prepend the Joomla site URL.

Solution: Parse the article.attributes.images JSON field and prepend the Joomla site base URL to all relative image paths. Also check that the introtext HTML body contains absolute URLs for any inline images — Joomla's RTE sometimes stores relative inline image paths that also need the base URL prepended.

typescript
1// Parse Joomla images field and build absolute URLs
2const images = article.attributes.images ? JSON.parse(article.attributes.images) : {};
3const introImageUrl = images.image_intro ? `${JOOMLA_SITE_URL}${images.image_intro}` : null;

Best practices

  • Always request only published articles using filter[state]=1 in API requests — Joomla returns all articles including unpublished ones to authenticated Super User API tokens, so the state filter is essential for public-facing content.
  • Map Joomla's JSON:API 'data[].attributes' response structure in a React hook or utility function that normalizes it to plain objects — this prevents repetitive data[n].attributes.field access throughout your components.
  • Parse Joomla's images field as JSON and prepend the site URL to relative image paths — Joomla stores intro and full-text image paths as a JSON string within the images attribute field, not as direct URL properties.
  • Use Joomla's pagination via page[offset] and page[limit] parameters for large article collections — avoid fetching all articles at once, as large Joomla sites can have thousands of articles.
  • Handle Joomla's multi-language setup by passing the Language filter (filter[language]={lang-code}) in API requests — Joomla stores multilingual content as separate articles tagged with language codes (en-GB, de-DE, etc.).
  • Cache Joomla category and menu data in Supabase with a 1-hour TTL — these structures change rarely and caching eliminates repeated API calls on every page load.
  • Create a dedicated read-only Joomla API user with minimal permissions rather than using the Super User token for frontend API calls — the Super User token has write access to all content and should be treated like a root database password.

Alternatives

Frequently asked questions

Does Joomla's Web Services API work with Joomla 3.x?

No. The built-in Web Services API (com_api) was introduced in Joomla 4.0. For Joomla 3.x sites, a third-party extension like FOF REST is required to expose a REST API, but the endpoint structure and authentication differ from the native Joomla 4 API. The integration pattern in this tutorial applies to Joomla 4.0 and newer. Consider upgrading to Joomla 4 or 5 if you are running Joomla 3 — Joomla 3 reached end of life in August 2023.

What is Joomla's JSON:API format and how does it differ from WordPress REST API?

Joomla uses the JSON:API specification (jsonapi.org) where each resource is structured as { data: { id, type, attributes: {...}, relationships: {...} } }. WordPress uses plain JSON objects with flat properties. In practice this means: for WordPress you access post.title.rendered directly, while for Joomla you access article.attributes.title. Joomla's format is more verbose but follows a formal specification that makes relationship navigation consistent.

How does Joomla's ACL affect which articles the API returns?

Joomla's ACL access levels (Public, Registered, Special, etc.) control content visibility. The API token authenticates as the token's associated user, and Joomla applies that user's group permissions when fetching content. A Super User token can access all access levels. A public user token can only access 'Public' content. Configure your API user's group membership in Joomla's User Manager to match the access level requirements of your Lovable app's public versus authenticated content.

Can I write data back to Joomla from my Lovable app?

Yes. The Joomla 4 Web Services API supports POST (create) and PATCH (update) operations for articles, contacts, and other resources. Pass the article data as a JSON:API body in a POST request to /api/index.php/v1/articles with the appropriate attributes. The API token must belong to a user with the 'Create' and 'Edit' permissions for the relevant category. This enables use cases like user-generated content submission from a Lovable form directly to the Joomla backend.

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.