Refract-CMS is an open source, code first, self-hosted headless CMS using React, Express & MongoDB.
Unlike most other CMS systems, the schema is defined in JavaScript/TypeScript, and we do not force developers to use elaborate GUI's.
Developers can live entirely in their chosen code editor, while content editors can utilize a blazing fast React based single-page-app, to manage content.
This approach has some advantages:
- It allows teams to properly code-review schema changes using their current git workflows.
- Your schema's can be copy/pasted between projects, or distributed using your organizations private NPM registry etc.
- Your schema can be deployed to multiple environments without requiring you to do duplicate work in a GUI or database imports, You just deploy the code and start editing.
- Clean database, Refract-CMS only creates one mongo collection per schema, as it doesn't have to store schema information in there.
npx @refract-cms/create --dir myapp
cd ./myapp
npm run dev
Create a ts
file inside directory: ./src/config/schemas
, e.g. product-schema.ts
import { composeSchema, createTextEditor, createBooleanEditor } from '@refract-cms/core';
export const ProductSchema = composeSchema({
options: {
alias: 'product',
displayName: 'Product',
instanceDisplayProps: (product) => ({
primaryText: product.title,
}),
},
properties: {
title: {
type: String,
displayName: 'Title',
editorComponent: createTextEditor(),
},
active: {
type: Boolean,
displayName: 'Active',
editorComponent: createBooleanEditor(),
},
},
});
Edit file ./src/config/index.ts
import { buildConfig } from '@refract-cms/core';
import { ProductSchema } from './schemas/product-schema';
export const config = buildConfig({
schema: [
ProductSchema,
// The rest of the schemas
],
});
The CMS exposes a GraphQL endpoint, with rich filtering that you can use to query data for your frontend apps.
Property editors for each property on the entity model are added to the schema in code, allowing you to choose between some of the in-built editors (TextBox, Select, Image) or to write your own using React.
This is just a standard React component, you can do whatever you want in here including async calls to API's. You receive the current value & a setValue function as props.
The props are typed based on what the target type for this editor is e.g. PropertyEditorProps<string>
or PropertyEditorProps<Date>
.
To apply styles is to utilize JSS useStyles
hook from material-ui.
import React from 'react';
import { PropertyEditorProps } from '@refract-cms/core';
import { makeStyles } from '@material-ui/core';
const useStyles = makeStyles((theme) => ({
paragraph: {
color: theme.palette.primary.main,
marginBottom: theme.spacing(),
},
}));
export function CustomTextEditor(props: PropertyEditorProps<string>) {
const classes = useStyles(props);
const { value, setValue } = props;
return (
<div>
<p className={classes.paragraph}>This is an example of a basic custom editor component</p>
<input value={value} onChange={(e) => setValue(e.target.value)} />
</div>
);
}
Add a reference to the custom editor component for the desired property in your schema:
myProperty: {
type: String,
displayName: 'My Property',
editorComponent: CustomTextEditor,
},
An Refract-CMS app is a standard NodeJS app that can be run anywhere that supports NodeJS or docker.
E.g
- Digital Ocean
- Azure
- AWS
- Kubernetes
The .env file is for local development. When deploying to production we recommend ommitting the .env file from the deployment & using environment variables.
Ensure the following environment varibles are set in your production environment:
- MONGO_URI
- ADMIN_USERNAME
- ADMIN_PASSWORD
- JWT_SECRET
npm run build
npm run start:prod
yarn
yarn dev