A set of React components and utilities for Directus Headless CMS.
Install this library along with @directus/sdk@
(version 10 or below):
Note: Directus SDK version 11 and upwards are currently not supported, but active work is in progress to add support for these versions in future releases.
npm install react-directus @directus/sdk@^10
The <DirectusProvider>
component makes the Directus JavaScript SDK available to any nested components that need to access it. The provider accepts the following props:
apiUrl
: the URL of your Directus APIoptions
(optional): an object containing the Directus client optionsautoLogin
(optional): iftrue
, the SDK will try to login using theaccessToken
stored in the browser's local storageonAutoLoginError
(optional): a callback function that is called when the auto-login fails
import { App } from './App';
import { DirectusProvider } from 'react-directus';
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'));
root.render(
<DirectusProvider apiUrl="https://api.example.com" options={{}}>
<App />
</DirectusProvider>
);
With TypeScript, you can use the optional generic collection type for Directus, as described in the Directus TypeScript documentation:
import { App } from './App';
import { DirectusProvider } from 'react-directus';
import { createRoot } from 'react-dom/client';
import MyCollections from './types';
const root = createRoot(document.getElementById('root'));
root.render(
<DirectusProvider<MyCollections> apiUrl="https://api.example.com" options={{}}>
<App />
</DirectusProvider>
);
After adding the provider, you can access the configured client anywhere in the app, using the useDirectus
hook:
import { useEffect, useState } from 'react';
import { useDirectus } from 'react-directus'
export const TodoList = () => {
// Get the Directus SDK object
const { directus } = useDirectus();
const [todos, setTodos] = useState([]);
useEffect(() => {
const fetchTodos = async () => {
const todos = (await directus.items('todos').readMany()).data;
setTodos(todos);
};
fetchTodos();
}, [directus]);
return todos.map(item => <TodoItem key={item.id} item={item} />);
};
The useDirectusAuth
hook provides a few methods for working with the Directus Authentication API:
login
- a function that accepts an email and password and returns a promise that resolves to the user object if the login is successful or rejects with an error otherwiselogout
- a function that logs out the current useruser
- the current user objectauthState
- the current authentication state, one ofloading
(the initial state),logged-in
orlogged-out
import { useDirectusAuth } from 'react-directus';
import { FormEvent } from 'react';
const Login = () => {
const { login } = useDirectusAuth();
const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
const { email, password } = e.currentTarget.elements;
login(email.value, password.value).catch(err => {
console.error(err);
});
};
return (
<form onSubmit={handleSubmit}>
<input type='email' name='email' />
<input type='password' name='password' />
<button type='submit'>Login</button>
</form>
);
};
export default Login;
This package contains a few components for working with Direcuts files. They are all configured for using the apiUrl
and accessToken
specified in the provider. Hopefully, more will come in the future 🤗.
Note: components can also be used in a "standalone" way, meaning that they are not bound to the
apiUrl
specified in the provider. In that case, they both accept anapiUrl
and an optionalaccessToken
prop.
Computes the URL of the given resource asset
, rendering it using the render
prop:
asset
: the asset representing the resource (string
orobject
with anid
property)download
: force browser to download the asset (force theContent-Disposition
header)render
: a function (which receives an object with theurl
property) that provides the component to render
import { DirectusAsset } from 'react-directus';
export const TodoItem = ({ item }) => {
return (
<div>
<h1>Todo #{item.id}</h1>
<DirectusAsset asset={item.attachment} download={true}
render={({ asset, url }) => <a href={url}>{asset.filename_download}</a>} />
</div>
);
};
Computes the URL of the given resource asset
, rendering it using the render
prop:
asset
: the asset representing the resource (string
orobject
with anid
property)render
: a function (which receives an object with theurl
property and all propertys provided toDirectusImage
) that provides the component to renderpresetKey
: the key of the Storage Asset Preset, a shortcut for the below parameters
Note: the following parameters are ignored if
presetKey
is provided
fit
: fit of the thumbnail while always preserving the aspect ratio, can be any of the following options:cover
,contain
,inside
oroutside
height
: height of the thumbnail in pixelswidth
: width of the thumbnail in pixelsquality
: quality of the thumbnail (1
to100
)format
: the return file formatwithoutEnlargement
: iftrue
, the thumbnail will not be larger than the original imagetransforms
: an array of Sharp transforms to apply to the image
import { DirectusImage } from 'react-directus';
export const TodoItem = ({ item }) => {
return (
<div>
<h1>Todo #{item.id}</h1>
<DirectusImage asset={item.image} fit="cover" quality="75"
render={({ asset, url }) => <img src={url} alt={asset.title} />} />
</div>
);
};
To make the project fully compatible with React Native you need to install the localstorage-polyfill package:
npm install localstorage-polyfill
Then import the module before any other import and force the storage mode "LocalStorage" in your Directus instance:
import 'localstorage-polyfill';
import { DirectusProvider } from 'react-directus';
import { View } from 'react-native';
export default function App({}) {
return (
<DirectusProvider
apiUrl='https://api.example.com'
options={{ storage: { mode: 'LocalStorage' } }}
>
<View />
</DirectusProvider>
)
}
In future releases, a solution using AsyncStorage
or an encrypted secure storage option is planned.
All types of contributions are encouraged and valued. See the Contributing guidelines, the community looks forward to your contributions!
This project is released under the under terms of the ISC License.