Manage Digital Ocean Spaces media assets in TinaCMS.
The following guide relies on NextJS's API functions to authenticate the 3rd-party media interactions. We hope to document a framework-agnostic approach soon.
yarn add next-tinacms-dos
npm install next-tinacms-dos
You need some credentials provided by Digital Ocean Spaces to set this up properly. If you do not already have an account, you can register here .
Add the following variables to an .env
file.
SPACES_ENDPOINT=<Your Digital Ocean Spaces Endpoint: ex. https://fra1.digitaloceanspaces.com> (Does not include the space name)SPACES_NAME=<Your Digital Ocean Spaces Name: ex. my-spaces>SPACES_KEY=<Your Digital Ocean Spaces access key>SPACES_SECRET_KEY=<Your Digital Ocean Spaces access secret>
You can register the Digital Ocean Space Media store via the loadCustomStore
prop.
The loadCustomStore
prop can be configured within tina/config.{js,ts,tsx}
.
//tina/config.{ts,js}//...export default defineConfig({//...media: {loadCustomStore: async () => {const pack = await import('next-tinacms-dos')return pack.TinaCloudDOSMediaStore},},})
Tina's "external media provider" support requires a light backend media handler, that needs to be setup/hosted by the user. There are multiple ways to do this, including the framework-agnostic Netlify Functions implementation.
NOTE: this step will show you how to set up an API route for Next.js. If you are using a different framework, you will need to set up your own API route.
Set up a new API route in the pages
directory of your Next.js app, e.g. pages/api/dos/[...media].ts
.
Then add a new catch all API route for media.
Call createMediaHandler
to set up routes and connect your instance of the Media Store to your Digital Ocean Spaces.
Import isAuthorized
from "@tinacms/auth".
The authorized
key will make it so only authorized users within TinaCloud can upload and make media edits.
// pages/api/dos/[...media].tsimport {mediaHandlerConfig,createMediaHandler,} from 'next-tinacms-dos/dist/handlers'import { isAuthorized } from '@tinacms/auth'export const config = mediaHandlerConfigexport default createMediaHandler({config: {endpoint: process.env.SPACES_ENDPOINT,credentials: {accessKeyId: process.env.SPACES_KEY || '',secretAccessKey: process.env.SPACES_SECRET_KEY || '',},region: 'us-east-1',},bucket: process.env.SPACES_NAME || '',authorized: async (req, _res) => {if (process.env.NODE_ENV === 'development') {return true}try {const user = await isAuthorized(req)return user && user.verified} catch (e) {console.error(e)return false}},})
For Netlify use case, please read how to set up Netlify Functions here
If you're using a custom URL for your Digital Ocean Spaces bucket, you can pass in a cdnUrl
value to createMediaHandler
.
export default createMediaHandler({config: ...,bucket: ...,authorized: ...,},{cdnUrl: "https://my-custom-domain.com"})
Now that the media store is registered and the API route for media set up, let's add an image to your schema.
In your schema add a new field for the image, e.g:
{name: 'hero',type: 'image',label: 'Hero Image',}
Now, when editing your site, the image field will allow you to connect to your Digital Ocean Spaces via the Media Store to manage your media assets.
© TinaCMS 2019–2024