DEV Community

Tea Reggi
Tea Reggi

Posted on • Edited on

Using Supabase as a database and image store with Strapi CMS.

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'),
      }
    },
  }, 
})
Enter fullscreen mode Exit fullscreen mode

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\""
}
Enter fullscreen mode Exit fullscreen mode

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',
];
Enter fullscreen mode Exit fullscreen mode

And it worked. Now I have a Strapi server wired up to use Supabase! Hope this helps someone out there.

Top comments (8)

Collapse
 
drimescodes profile image
drimescodes

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

Image description

my middleware.js

Image description

PS:This is my first time using strapi

Collapse
 
adamatronix profile image
Adam Gee

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?

Collapse
 
adamatronix profile image
Adam Gee

Sorry, for anyone making the same mistake, you need to use the sercret service role api key, not the anon/public one.

Collapse
 
sanditzz profile image
PO • Edited

This worked thank you! However, my thumbnails are not appearing. Any idea?

Image description

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.

Collapse
 
czapata08 profile image
Carlos Zapata

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?

Collapse
 
reggi profile image
Tea Reggi

Node.js v18.17.1 / "@strapi/strapi": "4.14.0",

Collapse
 
czapata08 profile image
Carlos Zapata • Edited

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?

Thread Thread
 
reggi profile image
Tea Reggi

I had to remove row level policies for the object store check the stack overflow link for deets