The Problem to Solve
My manager asked me to evaluate a CMS solution so the product team could maintain an FAQ and product knowledge base. Backend development capacity was limited, so the goal was to find something with a friendly UI that could quickly generate admin maintenance pages and frontend APIs — reducing the burden on frontend developers who would consume those APIs.
Why Strapi?

After trialing several mainstream CMS options, I landed on Strapi for the following reasons. It's flexible and lightweight, well-suited for long-term enterprise use, and can be repurposed for other needs down the road.
- End users: friendly UI, draggable field layout.
- Admins: field validation, permission management, workflow control.
- Developers: open source, developer-friendly API integration, built-in Swagger docs, extensibility via plugin marketplace, rich endpoints, and the project itself is built with React and Node.js — very approachable for frontend developers.
How It Works
Strapi uses a friendly admin UI to generate code from configuration.

Installation Constraints
- Node version:
>=10.16.0 <=14.x.x(use nvm to manage multiple Node versions) - Cloud-hosted version is paid; self-hosted is open source and permanently free
Install Strapi
npx create-strapi-app@latest my-project --quickstart
Install Swagger
cd my-project
npm run strapi install documentation
npm run build // 裝完一定要按 build 才會跑出按鈕
Common Issues After Installation
API Doesn't Return Images
By default, Strapi API responses don't include image fields. You need to add a populate query parameter to explicitly request the image fields you want returned.

API Permissions
By default, all API access requires a token. If you don't need authentication for a particular collection, go to Settings > USERS & PERMISSIONS PLUGIN > Roles, find your collection, and grant find and findOne permissions.

Rich Text Images Can't Be Previewed in Real Time
.env
HOST=0.0.0.0
PORT=1337
APP_KEYS=p285lmxQN6bZ90Dh870eIg,twHIadFFnSgVKyGgzcpnIQ,jgn83CaVHIPPnpSqsZPWGw,s2lTboydFrhkPRHJp4omQw
API_TOKEN_SALT=9LGnsz1zt4UpaKfCCQxEZQ==
ADMIN_JWT_SECRET=l7gG6CTUeK0502ns9FAKkw==
JWT_SECRET=mJg/1OqVkOeCiZcxiQfG5w==
WEBSITE=http://127.0.0.1:1337/
config/server.js
module.exports = ({ env }) => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 1337),
------
url: env('WEBSITE', 'http://127.0.0.1'),
------
app: {
keys: env.array('APP_KEYS'),
},
});
Data Backup
- Database: defaults to SQLite, located at
.tmp/data.db(also supports MySQL and MongoDB). - Static files: uploaded files are stored in
/public/uploads.
Feature Walkthrough
Dynamically Generated Admin Panel

Multi-image Upload

Upload Format Restrictions

Data Entry Screen

Dynamic Layout Adjustment

Webhooks

Roles

Permissions





























Comments