# How to Integrate a Custom Backend (Non-Strapi) with Luban H5

> Learn how to integrate a custom backend with Luban H5 by replacing the Strapi SDK with an Axios client and updating your Vuex store. Get your custom backend working seamlessly with Luban H5 today.

- Repository: [小小鲁班/luban-h5](https://github.com/ly525/luban-h5)
- Tags: how-to-guide
- Published: 2026-03-06

---

**To integrate a custom backend with Luban H5, replace the Strapi SDK wrapper in [`src/utils/strapi.js`](https://github.com/ly525/luban-h5/blob/main/src/utils/strapi.js) with a thin Axios-based client that implements the same five methods (`getEntry`, `getEntries`, `createEntry`, `updateEntry`, `deleteEntry`), then update the Vuex store imports in [`src/store/modules/work.js`](https://github.com/ly525/luban-h5/blob/main/src/store/modules/work.js) and component-level stores to use your new client while keeping the existing error handling and loading states intact.**

Luban H5 is an open-source visual page builder that ships with Strapi as its default headless CMS. While Strapi provides a quick start, many teams need to connect Luban H5 to existing Spring Boot services, Node.js APIs, or serverless functions. This guide shows you how to integrate a custom backend with Luban H5 by replacing the Strapi SDK layer without modifying the Vuex store logic or UI components.

## Architecture Overview

The front-end communicates with the backend through a thin abstraction layer. To swap Strapi for a custom backend, you only need to replace the HTTP client wrapper while preserving the Vuex action signatures.

| Layer | Current Implementation | What to Replace for a Custom Backend |
|-------|------------------------|--------------------------------------|
| **HTTP client** | `strapi-sdk-javascript` ([`src/utils/strapi.js`](https://github.com/ly525/luban-h5/blob/main/src/utils/strapi.js)) | A thin wrapper around **axios** that mimics the Strapi SDK methods (`createEntry`, `getEntry`, `getEntries`, `updateEntry`, `deleteEntry`). |
| **Vuex actions** | Import `strapi` and call its methods (`strapi.getEntry(...)`, `strapi.getEntries.bind(strapi)`, …) – see [`src/store/modules/work.js`](https://github.com/ly525/luban-h5/blob/main/src/store/modules/work.js) and component-level stores. | Call the custom wrapper instead – the action signatures stay exactly the same, so no other code changes are required. |
| **Backend** | Strapi (auto-generates `created_at`, `updated_at`, etc.) | Any RESTful service that respects the same URL patterns (`/works`, `/datasources`, `/script`, …) **or** you can map the original Strapi routes to your own endpoints via a proxy layer. |
| **Error handling** | Centralised in [`src/utils/http.js`](https://github.com/ly525/luban-h5/blob/main/src/utils/http.js) + `handleError` | Re-use the same `AxiosWrapper` – it already handles loading states and error notifications. Only the HTTP layer changes. |

## Step-by-Step Integration Guide

### Create a Custom API Client

Create a new file [`src/utils/api.js`](https://github.com/ly525/luban-h5/blob/main/src/utils/api.js) that exposes the same five methods as the Strapi SDK but uses vanilla Axios calls to your backend.

```javascript
// src/utils/api.js
import axios from 'axios'

const api = axios.create({
  baseURL: process.env.VUE_APP_API_ROOT || '/api',   // <-- point to your backend
  timeout: 15000
  // add any required headers (e.g., Authorization)
})

// Mimic Strapi SDK methods
export default {
  // GET /:type/:id
  getEntry (type, id) {
    return api.get(`${type}/${id}`).then(r => r.data)
  },
  // GET /:type?query
  getEntries (type, params) {
    return api.get(type, { params }).then(r => r.data)
  },
  // POST /:type
  createEntry (type, data) {
    return api.post(type, data).then(r => r.data)
  },
  // PUT /:type/:id
  updateEntry (type, id, data) {
    return api.put(`${type}/${id}`, data).then(r => r.data)
  },
  // DELETE /:type/:id
  deleteEntry (type, id) {
    return api.delete(`${type}/${id}`).then(r => r.data)
  }
}

```

*Reference:* the original Strapi wrapper lives in [[`src/utils/strapi.js`](https://github.com/ly525/luban-h5/blob/main/src/utils/strapi.js)](https://github.com/ly525/luban-h5/blob/master/front-end/h5/src/utils/strapi.js).

### Update Vuex Store Imports

Replace the Strapi import with your new API client in every store module. The method signatures remain identical, so only the import path and variable name change.

In [`src/store/modules/work.js`](https://github.com/ly525/luban-h5/blob/main/src/store/modules/work.js):

```diff
- import strapi from '@/utils/strapi'
+ import api from '@/utils/api'

```

In [`src/components/core/store/modules/work.js`](https://github.com/ly525/luban-h5/blob/main/src/components/core/store/modules/work.js), [`script.js`](https://github.com/ly525/luban-h5/blob/main/script.js), and [`data-source.js`](https://github.com/ly525/luban-h5/blob/main/data-source.js):

```diff
- import strapi from '@/utils/strapi'
+ import api from '@/utils/api'

```

Then rename usages inside actions:

```diff
- strapi.createEntry('works', new Work()).then(entry => { … })
+ api.createEntry('works', new Work()).then(entry => { … })

```

Do the same for `getEntry`, `getEntries`, `updateEntry`, and `deleteEntry`.

### Configure Environment Variables

Add a new environment variable to point to your custom backend:

```bash

# .env (create in front-end/h5/ if missing)

VUE_APP_API_ROOT=https://my-custom-backend.example.com/api

```

The Axios instance in [`api.js`](https://github.com/ly525/luban-h5/blob/main/api.js) reads this variable. If you want to keep Strapi as an optional fallback, add a feature flag:

```bash
VUE_APP_USE_STRAPI=false

```

### Adapt Your Backend Contract

Your custom backend must expose RESTful endpoints that match the resource names Luban H5 expects:

- `GET /works` – list all works
- `GET /works/:id` – fetch a single work
- `POST /works` – create a work
- `PUT /works/:id` – update a work
- `DELETE /works/:id` – delete a work

Same pattern for `/datasources`, `/script`, and `/workform`.

**Response shape:** Return JSON objects with the same fields Strapi would provide (`id`, `created_at`, `updated_at`, `pages`, `title`, etc.). The client only uses the `data` property from the Axios response (see [`src/utils/http.js`](https://github.com/ly525/luban-h5/blob/main/src/utils/http.js)).

### Handle Authentication (Optional)

If your backend requires JWT or session cookies, configure the Axios defaults in [`api.js`](https://github.com/ly525/luban-h5/blob/main/api.js):

```javascript
api.defaults.headers.common['Authorization'] = `Bearer ${token}`

```

The existing error handling in [`src/utils/http.js`](https://github.com/ly525/luban-h5/blob/main/src/utils/http.js) will automatically surface 401/403 messages to the user.

## Key Files Reference

| Role | File | Why It Matters |
|------|------|----------------|
| **Default Strapi wrapper** | [`front-end/h5/src/utils/strapi.js`](https://github.com/ly525/luban-h5/blob/main/front-end/h5/src/utils/strapi.js) | Shows the minimal API surface Luban expects. |
| **Vuex store that uses the wrapper** | [`front-end/h5/src/store/modules/work.js`](https://github.com/ly525/luban-h5/blob/main/front-end/h5/src/store/modules/work.js) | Demonstrates how the SDK is consumed throughout the app. |
| **Component-level stores** | `front-end/h5/src/components/core/store/modules/*` (e.g., [`work.js`](https://github.com/ly525/luban-h5/blob/main/work.js), [`script.js`](https://github.com/ly525/luban-h5/blob/main/script.js), [`data-source.js`](https://github.com/ly525/luban-h5/blob/main/data-source.js)) | All import `strapi`; they need the same replacement. |
| **HTTP helper** | [`front-end/h5/src/utils/http.js`](https://github.com/ly525/luban-h5/blob/main/front-end/h5/src/utils/http.js) | Provides unified loading and error handling – reused unchanged. |
| **Backend entry point (Strapi)** | [`back-end/h5-api/server.js`](https://github.com/ly525/luban-h5/blob/main/back-end/h5-api/server.js) | Illustrates the current server; useful for mapping URLs. |

## Summary

- **Luban H5** communicates with backends through a thin wrapper in [`src/utils/strapi.js`](https://github.com/ly525/luban-h5/blob/main/src/utils/strapi.js) that exposes only five methods: `getEntry`, `getEntries`, `createEntry`, `updateEntry`, and `deleteEntry`.
- To integrate a custom backend, create a new [`src/utils/api.js`](https://github.com/ly525/luban-h5/blob/main/src/utils/api.js) file using **Axios** that implements the same five methods but points to your RESTful API.
- Replace every `import strapi from '@/utils/strapi'` with `import api from '@/utils/api'` in Vuex store modules ([`src/store/modules/work.js`](https://github.com/ly525/luban-h5/blob/main/src/store/modules/work.js) and `src/components/core/store/modules/*`), then rename `strapi.xxx` calls to `api.xxx`.
- Configure the endpoint via `VUE_APP_API_ROOT` in your `.env` file.
- Ensure your backend respects the same resource routes (`/works`, `/datasources`, etc.) and JSON response shape that Strapi provides.

## Frequently Asked Questions

### Do I need to modify the Vue components to use a custom backend?

No. The Vue components interact with the backend exclusively through Vuex actions. Since you are only replacing the HTTP client wrapper that the actions import, the components remain unchanged. The existing `handleError` logic in [`src/utils/http.js`](https://github.com/ly525/luban-h5/blob/main/src/utils/http.js) continues to manage loading states and error notifications.

### What HTTP methods does Luban H5 expect from my backend?

Your backend must support standard RESTful operations mapped to the five wrapper methods: `GET` for `getEntry` and `getEntries`, `POST` for `createEntry`, `PUT` for `updateEntry`, and `DELETE` for `deleteEntry`. The resource paths should match Strapi's conventions (e.g., `/works`, `/datasources`, `/script`) or you must map them accordingly in your API client.

### Can I keep Strapi and add a custom backend simultaneously?

Yes. You can maintain both integrations by creating a factory function or a runtime switch in [`src/utils/backend.js`](https://github.com/ly525/luban-h5/blob/main/src/utils/backend.js) that checks an environment variable like `VUE_APP_USE_STRAPI`. Export the appropriate client based on the flag, then import `backend` instead of `strapi` or `api` in your Vuex modules. This allows you to toggle between backends without code changes.

### How do I handle file uploads if not using Strapi?

File uploads in Luban H5 typically target the `/upload` endpoint when using Strapi. For a custom backend, modify the [`api.js`](https://github.com/ly525/luban-h5/blob/main/api.js) wrapper to include an `upload` method that sends a `multipart/form-data` POST request to your file service endpoint (e.g., `/api/upload` or an S3 presigned URL). Ensure the response returns the file URL in the same format Strapi uses (`{ url: '...' }`) so the existing image and media components can consume it without modification.