• Stars
    star
    209
  • Rank 188,325 (Top 4 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 5 years ago
  • Updated 6 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Google Cloud Storage Upload Provider for Strapi

strapi-provider-upload-google-cloud-storage

npm version npm downloads coverage

Non-Official Google Cloud Storage Provider for Strapi Upload

Installation

Install the package from your app root directory

with npm

npm install @strapi-community/strapi-provider-upload-google-cloud-storage --save

or yarn

yarn add @strapi-community/strapi-provider-upload-google-cloud-storage

Create your Bucket on Google Cloud Storage

The bucket should be created with fine grained access control, as the plugin will configure uploaded files with public read access.

How to create a bucket ?

Where my bucket can be located ?

Setting up Google authentication

If you are deploying to a Google Cloud Platform product that supports Application Default Credentials (such as App Engine, Cloud Run, and Cloud Functions etc.), then you can skip this step.

If you are deploying outside GCP, then follow these steps to set up authentication:

  1. In the GCP Console, go to the Create service account key page.
  2. From the Service account list, select New service account.
  3. In the Service account name field, enter a name.
  4. From the Role list, select Cloud Storage > Storage Admin.
  5. Select JSON for Key Type
  6. Click Create. A JSON file that contains your key downloads to your computer.
  7. Copy the full content of the downloaded JSON file
  8. Open the Strapi configuration file
  9. Paste it into the "Service Account JSON" field (as string or JSON, be careful with indentation)

Setting up the configuration file

You will find below many examples of configurations, for each example :

  1. If you are deploying outside GCP, then follow the steps above Setting up Google authentication
  2. Set the #bucketName# field and replace Bucket-name by yours previously create
  3. Default baseUrl is working, but you can replace it by yours (if you use a custom baseUrl)
  4. Save the configuration file
  5. Enjoy !

Example with application default credentials (minimal setup)

This works only for deployment to GCP products such as App Engine, Cloud Run, and Cloud Functions etc.

Edit ./config/plugins.js

module.exports = {
    upload: {
      config: {
        provider: '@strapi-community/strapi-provider-upload-google-cloud-storage',
        providerOptions: {
            bucketName: '#bucketName#',
            publicFiles: false,
            uniform: false,
            basePath: '',
        },
      },
    },
    //...
}

If you set publicFiles to false, the assets will be signed on the Content Manager (not the Content API). Consequently, they will only be visible to users who are authenticated.

You can set the expiry time of the signed URL by setting the expires option in the providerOptions object. See more in expires.

Example with credentials for outside GCP account

Edit ./config/plugins.js

module.exports = {
    upload: {
      config: {
        provider: '@strapi-community/strapi-provider-upload-google-cloud-storage',
        providerOptions: {
            bucketName: '#bucketName#',
            publicFiles: true,
            uniform: false,
            serviceAccount: {}, // replace `{}` with your serviceAccount JSON object
            baseUrl: 'https://storage.googleapis.com/{bucket-name}',
            basePath: '',
        },
      },
    },
    //...
}

If you have different upload provider by environment, you can override plugins.js file by environment :

  • config/env/development/plugins.js
  • config/env/production/plugins.js

This file, under config/env/{env}/ will be overriding default configuration present in main folder config.

Example with environment variable

module.exports = ({ env }) => ({
    upload: {
      config: {
        provider: '@strapi-community/strapi-provider-upload-google-cloud-storage',
        providerOptions: {
          serviceAccount: env.json('GCS_SERVICE_ACCOUNT'),
          bucketName: env('GCS_BUCKET_NAME'),
          basePath: env('GCS_BASE_PATH'),
          baseUrl: env('GCS_BASE_URL'),
          publicFiles: env('GCS_PUBLIC_FILES'),
          uniform: env('GCS_UNIFORM'),
        },
      },
    },
    //...
});

Environment variable can be changed has your way.

Setting up strapi::security middlewares to avoid CSP blocked url

Edit ./config/middlewares.js

  • In the field img-src and media-src add your own CDN url, by default it's storage.googleapis.com but you need to add your own CDN url
module.exports = [
  'strapi::errors',
  {
    name: 'strapi::security',
    config: {
      contentSecurityPolicy: {
        useDefaults: true,
        directives: {
          'connect-src': ["'self'", 'https:'],
          'img-src': ["'self'", 'data:', 'blob:', 'storage.googleapis.com'],
          'media-src': ["'self'", 'data:', 'blob:', 'storage.googleapis.com'],
          upgradeInsecureRequests: null,
        },
      },
    },
  },
  'strapi::cors',
  'strapi::poweredBy',
  'strapi::logger',
  'strapi::query',
  'strapi::body',
  'strapi::favicon',
  'strapi::public',
];

How to configure variable ?

serviceAccount :

JSON data provide by Google Account (explained before). If you are deploying to a GCP product that supports Application Default credentials, you can leave this omitted, and authentication will work automatically.

Can be set as a String, JSON Object, or omitted.

bucketName :

The name of the bucket on Google Cloud Storage.

  • Required

You can find more information on Google Cloud documentation.

baseUrl :

Define your base Url, first is default value :

basePath :

Define base path to save each media document.

  • Optional

publicFiles:

Boolean to define a public attribute to file when upload file to storage.

  • Default value : true
  • Optional

uniform:

Boolean to define uniform access, when uniform bucket-level access is enabled.

  • Default value : false
  • Optional

skipCheckBucket:

Boolean to define skipCheckBucket, when skipCheckBucket is enabled, we skip to check if the bucket exist. It's useful for private bucket.

  • Default value : false
  • Optional

cacheMaxAge:

Number to set the cache-control header for uploaded files.

  • Default value : 3600
  • Optional

gzip:

Value to define if files are uploaded and stored with gzip compression.

  • Possible values: true, false, auto
  • Default value : auto
  • Optional

expires:

Value to define expiration time for signed URLS. Files are signed when publicFiles is set to false.

  • Possible values: Date, number, string
  • Default value : 900000 (15 minutes)
  • Max value : 604800000 (7 days)
  • Optional

metadata:

Function that is executed to compute the metadata for a file when it is uploaded.

When no function is provided, the following metadata is used:

{
  contentDisposition: `inline; filename="${file.name}"`,
  cacheControl: `public, max-age=${config.cacheMaxAge || 3600}`,
}
  • Default value: undefined
  • Optional

Example:

  metadata: (file) => ({
    cacheControl: `public, max-age=${60 * 60 * 24 * 7}`, // One week
    contentLanguage: 'en-US',
    contentDisposition: `attachment; filename="${file.name}"`,
  }),

The available properties can be found in the Cloud Storage JSON API documentation.

generateUploadFileName:

Function that is executed to generate the name of the uploaded file. This method can give more control over the file name and can for example be used to include a custom hashing function or dynamic path.

When no function is provided, the default algorithm is used.

  • Default value: undefined
  • Optional

Example:

  generateUploadFileName: async (file) => {
    const hash = await ...; // Some hashing function, for example MD-5
    const extension = file.ext.toLowerCase().substring(1);
    return `${extension}/${slugify(path.parse(file.name).name)}-${hash}.${extension}`;
  },

FAQ

Common errors

Uniform access

Error uploading file to Google Cloud Storage: Cannot insert legacy ACL for an object when uniform bucket-level access is enabled

When this error occurs, you need to set uniform variable to true.

Service Account JSON

Error: Error parsing data "Service Account JSON", please be sure to copy/paste the full JSON file

When this error occurs, it's probably because you have missed something with the service account json configuration.

Follow this step :

  • Open your ServiceAccount json file
  • Copy the full content of the file
  • Paste it under the variable ServiceAccount in plugins.js config file in JSON

Migration

Due to release of Strapi v4, you need to migrate your databases files informations. Follow our migration guide.

Links

Community support

  • GitHub (Bug reports, contributions)

You can also used official support platform of Strapi, and search @Lith (maintainer)

  • Discord (For live discussion with the Community and Strapi team)
  • Community Forum (Questions and Discussions)

License

See the MIT License file for licensing information.

More Repositories

1

awesome-strapi

A curated list of awesome things related to Strapi
JavaScript
1,500
star
2

strapi-tool-dockerize

Easy add support for docker to your strapi project
JavaScript
531
star
3

strapi-plugin-transformer

A plugin for Strapi Headless CMS that provides the ability to transform the API request or response.
JavaScript
138
star
4

strapi-plugin-local-image-sharp

Dynamically resize, format and optimize images based on url modifiers.
JavaScript
64
star
5

jekyll-strapi

Jekyll plugin to retrieve content from any Strapi API.
Ruby
57
star
6

strapi-plugin-io

A plugin for Socket IO integration with Strapi CMS.
JavaScript
55
star
7

strapi-plugin-publisher

A plugin for Strapi Headless CMS that provides the ability provides the ability to easily schedule publishing and unpublishing of any content type.
JavaScript
47
star
8

strapi-tool-deployify

Easy deploy strapi to cloud platforms
JavaScript
45
star
9

strapi-plugin-slugify

A plugin for Strapi Headless CMS that provides the ability to auto slugify a field for any content type.
JavaScript
45
star
10

strapi-plugin-redis

Plugin used to centralize management of Redis connections in Strapi
JavaScript
41
star
11

strapi-plugin-website-builder

A plugin for Strapi Headless CMS that provides the ability to trigger website builds manually, periodically or through model events.
JavaScript
35
star
12

strapi-plugin-url-alias

🌐 Unique, autogenerated URL paths.
TypeScript
21
star
13

strapi-plugin-protected-populate

JavaScript
20
star
14

strapi-typed-fronend

make strapi types compatible with frontend
TypeScript
14
star
15

website

The repo for the website development competition of the @strapi-community.
TypeScript
11
star
16

strapi-plugin-notes

A plugin for Strapi Headless CMS that provides the ability to add notes to entity records.
JavaScript
9
star
17

strapi-plugin-measurement-protocol

Send data to Google Analytics with Measurement Protocol.
JavaScript
8
star
18

jekyll-blog

Simple Jekyll blog powered by Strapi
Ruby
7
star
19

strapi-plugin-multitenancy

JavaScript
6
star
20

eslint-config

Shared eslint configuration for Strapi v4 plugins & applications.
JavaScript
5
star
21

strapi-plugin-audit

Audit Log plugin for Strapi v4
JavaScript
3
star
22

strapi-plugin-search

A Strapi CMS plugin that provides search engine agnostic sync support
TypeScript
3
star
23

strapi-ai-bot

Discord bot used by the Strapi Community Discord Server
JavaScript
3
star
24

website-backend

JavaScript
1
star
25

docus-theme

Vue
1
star