I love the idea of a headless CMS to maintain my own personal API. The goal is to have a central source for all your data, blog posts, link lists, even job history data for a resume, small blurbs, summaries, and I have one for a list of github projects.
I fell in love with Strapi a couple months back and was interested in revisiting the project I created locally. What's cool about it is you can create custom content types with their own fields and you get an API from it.
I also love Supabase I think it's a great service with a ton of useful parts, it's a full postgres database, and an API layer too, so you don't even need to use Strapi's api if you wanted to. Strapi could just be used to write data to Supabase. Strapi also supports media uploads, and rather then using AWS or GCP I liked the idea of everything being under one service.
Here's the setup on how to use Supabase as both your database and media storage.
Once you have a strapi project setup you need to simply set your env vars to your supabase credentials that's the easy part then you're interacting with supabase directly.
To get the image store to work I had a bunch of issues. I found a module on github https://github.com/crubier/strapi-provider-upload-supabase I ended up going with a more up to date fork https://github.com/arkivedao/strapi-provider-upload-supabase
you can npm install this by using the github url.
Create a new file config/plugins.ts
:
export default ({ env }) => ({
upload: {
config: {
provider: "strapi-provider-upload-supabase",
providerOptions: {
apiUrl: env('SUPABASE_API_URL'),
apiKey: env('SUPABASE_API_KEY'),
bucket: env('SUPABASE_BUCKET'),
directory: env('SUPABASE_DIRECTORY'),
}
},
},
})
Once I set this up I was getting this error:
{
"statusCode": "401",
"error": "Invalid JWT",
"message": "new row violates row-level security policy for table \"objects\""
}
I had to turn of RLS for the object store in order to get it to work using the answer found here: https://stackoverflow.com/questions/72861584/supabase-bucket-policy-to-insert-file-not-working
Then to get thumbnails to work locally I needed my config/middlewares.ts
file to look like this:
export default ({ env }) => [
'strapi::errors',
{
name: 'strapi::security',
config: {
contentSecurityPolicy: {
useDefaults: true,
directives: {
'connect-src': ["'self'", 'https:', 'http:'],
'img-src': [
"'self'",
'data:',
'blob:',
'res.cloudinary.com', // cloudinary images
'lh3.googleusercontent.com', // google avatars
'platform-lookaside.fbsbx.com', // facebook avatars
'dl.airtable.com', // strapi marketplace,
"market-assets.strapi.io",
env('SUPABASE_API_URL'),
],
'media-src': ["'self'", 'data:', 'blob:', env('SUPABASE_API_URL')],
upgradeInsecureRequests: null,
},
},
},
},
'strapi::cors',
'strapi::poweredBy',
'strapi::logger',
'strapi::query',
'strapi::body',
'strapi::session',
'strapi::favicon',
'strapi::public',
];
And it worked. Now I have a Strapi server wired up to use Supabase! Hope this helps someone out there.
Top comments (8)
For me I wanted to serve the images straight from cloudinary
Like the images would be saved on cloudinary instead of supabase directly cause cloudinary has more space limit, but somehow somehow, the images aren't showing in the frontend and not also showing in supabase.
my PLUGINS.js
my middleware.js
PS:This is my first time using strapi
I'm still getting
error: new row violates row-level security policy
when trying to upload images. I basically created policies for all actions in Supabase. Any ideas?Sorry, for anyone making the same mistake, you need to use the sercret service role api key, not the anon/public one.
This worked thank you! However, my thumbnails are not appearing. Any idea?
There's a message
Loading Strapi(node:28648) Warning: The upload provider "strapi-provider-upload-supabase" doesn't implement the uploadStream function. Strapi will fallback on the upload method. Some performance issues may occur.
when running develop locally as well. Not sure what it means.Thanks for the article, I'm also working with strapi and supabase. I'm curious to know which strapi and node version are you running?
Node.js v18.17.1 / "@strapi/strapi": "4.14.0",
Awesome man, I'm still trying to hook it up to my storage. I have set the policy but I'm encountering error code 500 "JWT Malformed". Any recommendations on setting up the policies?
I had to remove row level policies for the object store check the stack overflow link for deets