mirror of
https://github.com/strapi/strapi.git
synced 2026-01-07 12:45:45 +00:00
Merge branch 'master' into docs/fixLinks
This commit is contained in:
commit
0bd9832ad0
@ -4,6 +4,7 @@
|
||||
**/OLD/**
|
||||
testApp/**
|
||||
examples/**
|
||||
cypress/**
|
||||
packages/strapi-generate-plugin/files/admin/src/**
|
||||
packages/strapi-helper-plugin/**
|
||||
packages/strapi-plugin-users-permissions/admin/**
|
||||
|
||||
@ -64,9 +64,14 @@ module.exports = {
|
||||
{
|
||||
flatTernaryExpressions: false,
|
||||
SwitchCase: 1,
|
||||
ignoredNodes: ['ConditionalExpression', "VariableDeclarator[kind='const']"],
|
||||
ignoredNodes: [
|
||||
'ConditionalExpression',
|
||||
"VariableDeclarator[kind='const']",
|
||||
'TemplateLiteral',
|
||||
],
|
||||
},
|
||||
],
|
||||
'template-curly-spacing': 0,
|
||||
'func-names': ['error', 'never'],
|
||||
'function-paren-newline': 0,
|
||||
'implicit-arrow-linebreak': 0,
|
||||
|
||||
5
.github/ISSUE_TEMPLATE.md
vendored
5
.github/ISSUE_TEMPLATE.md
vendored
@ -1,5 +0,0 @@
|
||||
<!--
|
||||
|
||||
Please use one of these issue templates: https://github.com/strapi/strapi/issues/new/choose
|
||||
|
||||
-->
|
||||
32
.github/ISSUE_TEMPLATE/DISCUSSION.md
vendored
32
.github/ISSUE_TEMPLATE/DISCUSSION.md
vendored
@ -1,32 +0,0 @@
|
||||
---
|
||||
name: 💬 Discussion
|
||||
about: Create a discussion topic. This is used to discuss changes before an RFC is made.
|
||||
---
|
||||
|
||||
<!--
|
||||
Hello 👋 Thank you for submitting a discussion topic.
|
||||
|
||||
To make your topic readable make sure you use valid Markdown syntax.
|
||||
|
||||
https://guides.github.com/features/mastering-markdown/
|
||||
|
||||
DO NOT USE THIS TEMPLATE for issues that are not related RFCs, for bug reports/feature requests please use the proper template.
|
||||
-->
|
||||
|
||||
- [ ] I have created an RFC on the [Strapi RFC Repo](https://github.com/strapi/rfcs)
|
||||
- [ ] I have checked for existing RFCs before creating this discussion topic
|
||||
|
||||
**Describe the topic**
|
||||
A clear and concise description of what the topic is.
|
||||
|
||||
**Your suggestions for this topic**
|
||||
Clear and simple suggestions for how you think this should be handled.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your points.
|
||||
|
||||
**Code snippets**
|
||||
If applicable, add code samples to help explain your points.
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Strapi Questions and Discussions
|
||||
url: https://github.com/strapi/strapi/discussions/new
|
||||
about: Please ask and answer questions here.
|
||||
13
.stylelintrc
Normal file
13
.stylelintrc
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"processors": [
|
||||
"stylelint-processor-styled-components"
|
||||
],
|
||||
"extends": [
|
||||
"stylelint-config-recommended",
|
||||
"stylelint-config-styled-components"
|
||||
],
|
||||
"rules": {
|
||||
"font-family-no-missing-generic-family-keyword": null,
|
||||
"no-descending-specificity": null
|
||||
}
|
||||
}
|
||||
@ -143,7 +143,7 @@ Before submitting an issue you need to make sure:
|
||||
- You are not asking a question about how to use Strapi or about whether or not Strapi has a certain feature. For general help using Strapi, you may:
|
||||
- Refer to [the official Strapi documentation](http://strapi.io).
|
||||
- Ask a member of the community in the [Strapi Slack Community](https://slack.strapi.io/).
|
||||
- Ask a question on [StackOverflow](http://stackoverflow.com/questions/tagged/strapi).
|
||||
- Ask a question on [Github Discussions](https://github.com/strapi/strapi/discussions).
|
||||
- Your issue title is concise, on-topic and polite.
|
||||
- You can and do provide steps to reproduce your issue.
|
||||
- You have tried all the following (if relevant) and your issue remains:
|
||||
|
||||
@ -115,10 +115,9 @@ Please read our [Contributing Guide](./CONTRIBUTING.md) before submitting a Pull
|
||||
|
||||
For general help using Strapi, please refer to [the official Strapi documentation](https://strapi.io/documentation/). For additional help, you can use one of these channels to ask a question:
|
||||
|
||||
- [StackOverflow](http://stackoverflow.com/questions/tagged/strapi)
|
||||
- [Slack](http://slack.strapi.io) (Highly recommended for faster support)
|
||||
- [Spectrum](https://spectrum.chat/strapi)
|
||||
- [GitHub](https://github.com/strapi/strapi) (Bug reports, contributions)
|
||||
- [Slack](http://slack.strapi.io) (For live discussion with the Community and Strapi team)
|
||||
- [GitHub](https://github.com/strapi/strapi) (Bug reports, Contributions)
|
||||
- [GitHub Discussions](https://github.com/strapi/strapi/discussions) (Questions and Discussions)
|
||||
- [ProductBoard](https://portal.productboard.com/strapi/tabs/2-under-consideration) (Roadmap, Feature requests)
|
||||
- [Twitter](https://twitter.com/strapijs) (Get the news fast)
|
||||
- [Facebook](https://www.facebook.com/Strapi-616063331867161)
|
||||
|
||||
@ -1,8 +1,5 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
require.resolve('@babel/preset-env'),
|
||||
require.resolve('@babel/preset-react'),
|
||||
],
|
||||
presets: [require.resolve('@babel/preset-env'), require.resolve('@babel/preset-react')],
|
||||
plugins: [
|
||||
'@babel/plugin-proposal-class-properties',
|
||||
'@babel/plugin-syntax-dynamic-import',
|
||||
|
||||
@ -214,7 +214,6 @@ module.exports = {
|
||||
'/3.0.0-beta.x/guides/secure-your-app',
|
||||
'/3.0.0-beta.x/guides/send-email',
|
||||
'/3.0.0-beta.x/guides/registering-a-field-in-admin',
|
||||
'/3.0.0-beta.x/guides/count-graphql',
|
||||
'/3.0.0-beta.x/guides/client',
|
||||
'/3.0.0-beta.x/guides/update-version',
|
||||
],
|
||||
|
||||
@ -388,7 +388,7 @@ Forbidden Access Looks like this:
|
||||
|
||||
- Learn how to use Strapi with React ([Gatsby](https://blog.strapi.io/building-a-static-website-using-gatsby-and-strapi) or [Next.js](https://blog.strapi.io/strapi-next-setup/)) or Vue.js ([Nuxt.js](https://blog.strapi.io/cooking-a-deliveroo-clone-with-nuxt-vue-js-graphql-strapi-and-stripe-setup-part-1-7/)).
|
||||
- Read the [concepts](../concepts/concepts.html) and [articles](../articles/) to deep dive into Strapi.
|
||||
- Get help on [StackOverflow](https://stackoverflow.com/questions/tagged/strapi).
|
||||
- Get help on [Github Discussions](https://github.com/strapi/strapi/discussions).
|
||||
- Read the [source code](https://github.com/strapi/strapi), [contribute](https://github.com/strapi/strapi/blob/master/CONTRIBUTING.md) or [give a star](https://github.com/strapi/strapi) on GitHub.
|
||||
- Follow us on [Twitter](https://twitter.com/strapijs) to get the latest news.
|
||||
- [Join the vibrant and active Strapi community](https://slack.strapi.io) on Slack.
|
||||
|
||||
@ -78,7 +78,7 @@ Here we are! The list of **restaurants** is accessible at [`http://localhost:133
|
||||
|
||||
- Learn how to use Strapi with React ([Gatsby](https://blog.strapi.io/building-a-static-website-using-gatsby-and-strapi) or [Next.js](https://blog.strapi.io/strapi-next-setup/)) or Vue.js ([Nuxt.js](https://blog.strapi.io/cooking-a-deliveroo-clone-with-nuxt-vue-js-graphql-strapi-and-stripe-setup-part-1-7/)).
|
||||
- Read the [concepts](../concepts/concepts.html) and [articles](../articles/) to deep dive into Strapi.
|
||||
- Get help on [StackOverflow](https://stackoverflow.com/questions/tagged/strapi).
|
||||
- Get help on [Github Discussions](https://github.com/strapi/strapi/discussions).
|
||||
- Read the [source code](https://github.com/strapi/strapi), [contribute](https://github.com/strapi/strapi/blob/master/CONTRIBUTING.md) or [give a star](https://github.com/strapi/strapi) on GitHub.
|
||||
- Follow us on [Twitter](https://twitter.com/strapijs) to get the latest news.
|
||||
- [Join the vibrant and active Strapi community](https://slack.strapi.io) on Slack.
|
||||
|
||||
@ -28,7 +28,7 @@ axios
|
||||
})
|
||||
.catch(error => {
|
||||
// Handle error.
|
||||
console.log('An error occurred:', error);
|
||||
console.log('An error occurred:', error.response);
|
||||
});
|
||||
```
|
||||
|
||||
@ -57,7 +57,7 @@ axios
|
||||
})
|
||||
.catch(error => {
|
||||
// Handle error.
|
||||
console.log('An error occurred:', error);
|
||||
console.log('An error occurred:', error.response);
|
||||
});
|
||||
```
|
||||
|
||||
@ -86,7 +86,7 @@ axios
|
||||
})
|
||||
.catch(error => {
|
||||
// Handle error.
|
||||
console.log('An error occurred:', error);
|
||||
console.log('An error occurred:', error.response);
|
||||
});
|
||||
```
|
||||
|
||||
@ -139,8 +139,7 @@ import axios from 'axios';
|
||||
axios
|
||||
.post('http://localhost:1337/auth/forgot-password', {
|
||||
email: 'user@strapi.io',
|
||||
url:
|
||||
'http:/localhost:1337/admin/plugins/users-permissions/auth/reset-password',
|
||||
url: 'http:/localhost:1337/admin/plugins/users-permissions/auth/reset-password',
|
||||
})
|
||||
.then(response => {
|
||||
// Handle success.
|
||||
@ -148,7 +147,7 @@ axios
|
||||
})
|
||||
.catch(error => {
|
||||
// Handle error.
|
||||
console.log('An error occurred:', error);
|
||||
console.log('An error occurred:', error.response);
|
||||
});
|
||||
```
|
||||
|
||||
@ -176,7 +175,7 @@ axios
|
||||
})
|
||||
.catch(error => {
|
||||
// Handle error.
|
||||
console.log('An error occurred:', error);
|
||||
console.log('An error occurred:', error.response);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
@ -10,19 +10,19 @@ To apply your changes you need to [rebuild](#build) your admin panel
|
||||
|
||||
By default, the administration panel is exposed via [http://localhost:1337/admin](http://localhost:1337/admin). However, for security reasons, you can easily update this path.
|
||||
|
||||
**Path —** `./config/environment/**/server.json`.
|
||||
**Path —** `./config/server.js`.
|
||||
|
||||
```json
|
||||
{
|
||||
"host": "localhost",
|
||||
"port": 1337,
|
||||
"cron": {
|
||||
"enabled": false
|
||||
```js
|
||||
module.exports = {
|
||||
host: 'localhost',
|
||||
port: 1337,
|
||||
cron: {
|
||||
enabled: false,
|
||||
},
|
||||
"admin": {
|
||||
"path": "/dashboard"
|
||||
}
|
||||
}
|
||||
admin: {
|
||||
path: '/dashboard',
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
The panel will be available through [http://localhost:1337/dashboard](http://localhost:1337/dashboard) with the configurations above.
|
||||
@ -31,19 +31,19 @@ The panel will be available through [http://localhost:1337/dashboard](http://loc
|
||||
|
||||
By default, the administration panel client host name is `localhost`. However, you can change this setting by updating the `admin` configuration:
|
||||
|
||||
**Path —** `./config/environment/**/server.json`.
|
||||
**Path —** `./config/server.js`.
|
||||
|
||||
```json
|
||||
{
|
||||
"host": "localhost",
|
||||
"port": 1337,
|
||||
"cron": {
|
||||
"enabled": false
|
||||
```js
|
||||
module.exports = {
|
||||
host: 'localhost',
|
||||
port: 1337,
|
||||
cron: {
|
||||
enabled: false,
|
||||
},
|
||||
"admin": {
|
||||
"host": "my-host"
|
||||
}
|
||||
}
|
||||
admin: {
|
||||
host: 'my-host',
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## Development mode
|
||||
@ -86,43 +86,6 @@ const trads = {
|
||||
export default trads;
|
||||
```
|
||||
|
||||
**Path --** `my-app/admin/src/i18n.js`
|
||||
|
||||
```js
|
||||
import { addLocaleData } from 'react-intl';
|
||||
import { reduce } from 'lodash';
|
||||
import en from 'react-intl/locale-data/en';
|
||||
import fr from 'react-intl/locale-data/fr';
|
||||
import trads from './translations';
|
||||
|
||||
// We dismiss pt-BR and zh-Hans locales since they are not supported by react-intl
|
||||
const locales = {
|
||||
en,
|
||||
fr,
|
||||
};
|
||||
const languages = Object.keys(trads);
|
||||
|
||||
/**
|
||||
* Dynamically generate `translationsMessages object`.
|
||||
*/
|
||||
const translationMessages = reduce(
|
||||
languages,
|
||||
(result, language) => {
|
||||
const obj = result;
|
||||
obj[language] = trads[language];
|
||||
|
||||
if (locales[language]) {
|
||||
addLocaleData(locales[language]);
|
||||
}
|
||||
|
||||
return obj;
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
export { languages, translationMessages };
|
||||
```
|
||||
|
||||
::: tip
|
||||
With this modification only English and French will be available in your admin
|
||||
:::
|
||||
@ -195,19 +158,19 @@ export const SETTINGS_BASE_URL = '/settings';
|
||||
|
||||
By default, the front-development server runs on the `8000` port. However, you can change this setting by updating the following configuration:
|
||||
|
||||
**Path —** `./config/environment/**/server.json`.
|
||||
**Path —** `./config/server.js`.
|
||||
|
||||
```json
|
||||
{
|
||||
"host": "localhost",
|
||||
"port": 1337,
|
||||
"cron": {
|
||||
"enabled": false
|
||||
```js
|
||||
module.exports = {
|
||||
host: 'localhost',
|
||||
port: 1337,
|
||||
cron: {
|
||||
enabled: false,
|
||||
},
|
||||
"admin": {
|
||||
"port": 3000
|
||||
}
|
||||
}
|
||||
admin: {
|
||||
port: 3000,
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## Build
|
||||
@ -242,34 +205,4 @@ strapi build
|
||||
|
||||
::::
|
||||
|
||||
you can build your admin panel with a specific configuration (located in the `./config/environments/**/server.json`) config by specifying a NODE_ENV as follows:
|
||||
|
||||
:::: tabs
|
||||
|
||||
::: tab yarn
|
||||
|
||||
```
|
||||
NODE_ENV=production yarn build
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
::: tab npm
|
||||
|
||||
```
|
||||
NODE_ENV=production npm run build
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
::: tab strapi
|
||||
|
||||
```
|
||||
NODE_ENV=production strapi build
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
::::
|
||||
|
||||
This will replace the folder's content located at `./build`. Visit [http://localhost:1337/admin](http://localhost:1337/admin) to make sure your updates have been taken into account.
|
||||
|
||||
@ -13,19 +13,19 @@ You don't need to touch anything in your configuration file. This is the default
|
||||
|
||||
You might want to change the path to access to the administration panel. Here the required configurations to change the path:
|
||||
|
||||
**Path —** `./config/environment/**/server.json`.
|
||||
**Path —** `./config/server.js`.
|
||||
|
||||
```js
|
||||
{
|
||||
"host": "localhost",
|
||||
"port": 1337,
|
||||
"cron": {
|
||||
"enabled": false
|
||||
module.exports = {
|
||||
host: 'localhost',
|
||||
port: 1337,
|
||||
cron: {
|
||||
enabled: false,
|
||||
},
|
||||
"admin": {
|
||||
"path": "/dashboard" // We change the path to access to the admin (highly recommended for security reasons).
|
||||
}
|
||||
}
|
||||
admin: {
|
||||
path: '/dashboard', // We change the path to access to the admin (highly recommended for security reasons).
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
**You have to rebuild the administration panel to make this work.** [Build instructions](./customization.md#build).
|
||||
@ -34,23 +34,23 @@ You might want to change the path to access to the administration panel. Here th
|
||||
|
||||
It's very common to deploy the front-end and the back-end on different servers. Here are the required configurations to handle this case:
|
||||
|
||||
**Path —** `./config/environment/**/server.json`.
|
||||
**Path —** `./config/server.js`.
|
||||
|
||||
```js
|
||||
{
|
||||
"host": "localhost",
|
||||
"port": 1337,
|
||||
"cron": {
|
||||
"enabled": false
|
||||
module.exports = {
|
||||
host: 'localhost',
|
||||
port: 1337,
|
||||
cron: {
|
||||
enabled: false,
|
||||
},
|
||||
"admin": {
|
||||
"path": "/", // Note: The administration will be accessible from the root of the domain (ex: http//yourfrontend.com/)
|
||||
"serveAdminPanel": false, // http://yourbackend.com will not serve any static admin files
|
||||
"build": {
|
||||
"backend": "http://yourbackend.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
admin: {
|
||||
path: '/', // Note: The administration will be accessible from the root of the domain (ex: http//yourfrontend.com/)
|
||||
serveAdminPanel: false, // http://yourbackend.com will not serve any static admin files
|
||||
build: {
|
||||
backend: 'http://yourbackend.com',
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
The administration URL will be `http://yourfrontend.com` and every request from the panel will hit the backend at `http://yourbackend.com`.
|
||||
@ -59,22 +59,22 @@ The administration URL will be `http://yourfrontend.com` and every request from
|
||||
|
||||
In this case, we suppose that you decided to put your administration panel on a different server than the API.
|
||||
|
||||
**Path —** `./config/environment/**/server.json`.
|
||||
**Path —** `./config/server.js`.
|
||||
|
||||
```js
|
||||
{
|
||||
"host": "localhost",
|
||||
"port": 1337,
|
||||
"cron": {
|
||||
"enabled": false
|
||||
module.exports = {
|
||||
host: 'localhost',
|
||||
port: 1337,
|
||||
cron: {
|
||||
enabled: false,
|
||||
},
|
||||
"admin": {
|
||||
"path": "/dashboard",
|
||||
"build": {
|
||||
"backend": "http://yourbackend.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
admin: {
|
||||
path: '/dashboard',
|
||||
build: {
|
||||
backend: 'http://yourbackend.com',
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
The administration URL will be `http://yourfrontend.com/dashboard` and every request from the panel will hit the backend at `http://yourbackend.com`.
|
||||
|
||||
@ -61,11 +61,6 @@ Start a Strapi application with autoReload disabled.
|
||||
This commands is there to run a Strapi application without restarts and file writes (aimed at production usage).
|
||||
Certain features are disabled in the `strapi start` mode because they require application restarts.
|
||||
|
||||
::: tip
|
||||
You can specify a NODE_ENV to use the configurations in the `./config/environments/[development|staging|production]` folder.
|
||||
By default the `development` environment will be used.
|
||||
:::
|
||||
|
||||
## strapi build
|
||||
|
||||
Builds your admin panel.
|
||||
@ -83,11 +78,68 @@ options: [--no-optimization]
|
||||
- **strapi build --no-optimization**<br/>
|
||||
Builds the administration panel without minimizing the assets. The build duration is faster.
|
||||
|
||||
::: tip
|
||||
You can specify a NODE_ENV to use the configurations in the `./config/environments/[development|staging|production]` folder.
|
||||
By default the `development` environment will be used.
|
||||
## strapi configuration:dump|config:dump
|
||||
|
||||
Dumps configurations to a file or stdout to help you migrate to production.
|
||||
|
||||
The dump format will be a JSON array.
|
||||
|
||||
```
|
||||
strapi configuration:dump
|
||||
|
||||
Options:
|
||||
-f, --file <file> Output file, default output is stdout
|
||||
```
|
||||
|
||||
**Examples**
|
||||
|
||||
- `strapi configuration:dump -f dump.json`
|
||||
- `strapi config:dump --file dump.json`
|
||||
- `strapi config:dump > dump.json`
|
||||
|
||||
All these examples are equivalent.
|
||||
|
||||
::: warning
|
||||
When configuring your application you often enter credentials for thrid party services (e.g authentication providers). Be aware that those credentials will also be dumped into the output of this command.
|
||||
In case of doubt, you should avoid committing the dump file into a versioning system. Here are some methods you can explore:
|
||||
|
||||
- Copy the file directly to the environment you want and run the restore command there.
|
||||
- Put the file in a secure location and download it at deploy time with the right credentials.
|
||||
- Encrypt the file before committing and decrypt it when running the restore command.
|
||||
|
||||
:::
|
||||
|
||||
## strapi configuration:restore|config:restore
|
||||
|
||||
Restores a configuration dump into your application.
|
||||
|
||||
The input format must be a JSON array.
|
||||
|
||||
```
|
||||
strapi configuration:restore
|
||||
|
||||
Options:
|
||||
-f, --file <file> Input file, default input is stdin
|
||||
-s, --strategy <strategy> Strategy name, one of: "replace", "merge", "keep". Defaults to: "replace"
|
||||
```
|
||||
|
||||
**Examples**
|
||||
|
||||
- `strapi configuration:restore -f dump.json`
|
||||
- `strapi config:restore --file dump.json -s replace`
|
||||
- `cat dump.json | strapi config:restore`
|
||||
- `strapi config:restore < dump.json`
|
||||
|
||||
All these examples are equivalent.
|
||||
|
||||
**Strategies**
|
||||
|
||||
When running the restore command, you can choose from three different strategies:
|
||||
|
||||
- **replace**: Will create missing keys and replace existing ones.
|
||||
- **merge**: Will create missing keys and merge existing keys whith there new value.
|
||||
- **keep**: Will create missing keys and keep existing keys as is.
|
||||
|
||||
## strapi generate:api
|
||||
|
||||
Scaffold a complete API with its configurations, controller, model and service.
|
||||
|
||||
@ -2,54 +2,186 @@
|
||||
sidebarDepth: 2
|
||||
---
|
||||
|
||||
# Configurations
|
||||
# Configuration
|
||||
|
||||
The main configurations of the project are located in the `./config` directory. Additional configs can be added in the `./api/**/config` folder of each API and plugin by creating JavaScript or JSON files.
|
||||
Your application configuration lives in the `config` folder. All the configuration files are loaded on startup and can be accessed through the configuration provider.
|
||||
|
||||
## Application
|
||||
When you have a file `./config/server.js` with the following config:
|
||||
|
||||
Contains the main configurations relative to your project.
|
||||
```js
|
||||
module.exports = {
|
||||
host: '0.0.0.0',
|
||||
};
|
||||
```
|
||||
|
||||
These configurations are accessible through `strapi.config.favicon` and `strapi.config.public`.
|
||||
You can access it as
|
||||
|
||||
**Path —** `./config/application.json`.
|
||||
```js
|
||||
strapi.config.get('server.host', 'defaultValueIfUndefined');
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"favicon": {
|
||||
"path": "favicon.ico",
|
||||
"maxAge": 86400000
|
||||
Nested keys are accessible with `dot-notation`.
|
||||
|
||||
:::tip NOTE
|
||||
You can notice the filename is used as prefix to access the configurations.
|
||||
:::
|
||||
|
||||
## Formats
|
||||
|
||||
You can either use `.js` or `.json` files to configure your application.
|
||||
|
||||
When using a `.js` you can either export an object:
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
mySecret: 'someValue',
|
||||
};
|
||||
```
|
||||
|
||||
or a function returning a configuration object (recommended usage). The function will get access to the [`env` utility](#casting-environment-variables).
|
||||
|
||||
```js
|
||||
module.exports = ({ env }) => {
|
||||
return {
|
||||
mySecret: 'someValue',
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
## Environment variables
|
||||
|
||||
In most usecases you will have different configurations between your environments. For example: your database credentials.
|
||||
|
||||
Instead of writting those credentials into your configuration files, you can define those variables in a `.env` file at the root of your application.
|
||||
|
||||
**Example**
|
||||
|
||||
```
|
||||
DATABASE_PASSWORD=acme
|
||||
```
|
||||
|
||||
If you want to customize the path of the `.env` file to load you can set an environment variable called `ENV_PATH` before starting your application:
|
||||
|
||||
```sh
|
||||
$ ENV_PATH=/absolute/path/to/.env npm run start
|
||||
```
|
||||
|
||||
Now you can access those variables in your configuration files and application. You can use `process.env.{varName}` to access those variables anywhere.
|
||||
|
||||
In your configuration files you will have access to a `env` utility that allows defining defaults and casting values.
|
||||
|
||||
`config/database.js`
|
||||
|
||||
```js
|
||||
module.exports = ({ env }) => ({
|
||||
connections: {
|
||||
default: {
|
||||
settings: {
|
||||
password: env('DATABASE_PASSWORD'),
|
||||
},
|
||||
},
|
||||
},
|
||||
"public": {
|
||||
"path": "./public",
|
||||
"maxAge": 60000,
|
||||
"defaultIndex": true
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
- `favicon`
|
||||
- `path` (string): Path to the favicon file. Default value: `favicon.ico`.
|
||||
- `maxAge` (integer): Cache-control max-age directive in ms. Default value: `86400000`.
|
||||
- `public`
|
||||
- `path` (string): Path to the public folder. Default value: `./public`.
|
||||
- `maxAge` (integer): Cache-control max-age directive in ms. Default value: `60000`.
|
||||
- `defaultIndex` (boolean): Display default index page at `/` and `/index.html`. Default value: `true`.
|
||||
### Casting environment variables
|
||||
|
||||
## Custom
|
||||
```js
|
||||
// Returns the env if defined without casting it
|
||||
env('VAR', 'default');
|
||||
|
||||
Add custom configurations to the project. The content of this file is available through the `strapi.config` object.
|
||||
// Cast to int (using parseInt)
|
||||
env.int('VAR', 0);
|
||||
|
||||
**Path —** `./config/custom.json`.
|
||||
// Cast to float (using parseFloat)
|
||||
env.float('VAR', 3.14);
|
||||
|
||||
```json
|
||||
{
|
||||
"providerURL": "https://provider.com",
|
||||
"mainColor": "blue"
|
||||
}
|
||||
// Cast to boolean (check if the value is equal to 'true')
|
||||
env.bool('VAR', true);
|
||||
|
||||
// Cast to js object (using JSON.parse)
|
||||
env.json('VAR', { key: 'value' });
|
||||
|
||||
// Cast to an array (syntax: ENV_VAR=[value1, value2, value3] | ENV_VAR=["value1", "value2", "value3"])
|
||||
env.array('VAR', [1, 2, 3]);
|
||||
|
||||
// Case to date (using new Date(value))
|
||||
env.date('VAR', new Date());
|
||||
```
|
||||
|
||||
These configurations are accessible through `strapi.config.providerURL` and `strapi.config.mainColor`.
|
||||
## Environments
|
||||
|
||||
What if you need to specific static configurations for specific environments and using environement variables becomes tedious ?
|
||||
|
||||
Strapi configurations can also be created per environment in `./config/env/{env}/{filename}`. These configurations will be merged into the base ones defined in the `./config` folder.
|
||||
The environment is based on the `NODE_ENV` environment variable (defaults to `development`).
|
||||
|
||||
When starting strapi with `NODE_ENV=production` it will load the configuration from `./config/*` and `./config/env/production/*`. Everything defined in the production config will override the default config.
|
||||
|
||||
In combination with environment variables this pattern becomes really powerfull:
|
||||
|
||||
**Example**
|
||||
|
||||
`./config/server.js`
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
host: '127.0.0.1',
|
||||
};
|
||||
```
|
||||
|
||||
`./config/env/production/server.js`
|
||||
|
||||
```js
|
||||
module.exports = ({ env }) => ({
|
||||
host: env('HOST', '0.0.0.0'),
|
||||
});
|
||||
```
|
||||
|
||||
When you start your application
|
||||
|
||||
```bash
|
||||
yarn start
|
||||
# uses host 127.0.0.0
|
||||
```
|
||||
|
||||
```bash
|
||||
NODE_ENV=production yarn start
|
||||
# uses host 0.0.0.0
|
||||
```
|
||||
|
||||
```bash
|
||||
HOST=10.0.0.1 NODE_ENV=production yarn start
|
||||
# uses host 10.0.0.1
|
||||
```
|
||||
|
||||
## Server
|
||||
|
||||
**Path —** `./config/server.js`.
|
||||
|
||||
```js
|
||||
module.exports = ({ env }) => ({
|
||||
host: env('HOST', '0.0.0.0'),
|
||||
port: env.int('PORT', 1337),
|
||||
});
|
||||
```
|
||||
|
||||
**Available options**
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | ----------- |
|
||||
| `host` | Host name | string | `localhost` |
|
||||
| `port` | Port on which the server should be running. | integer | `1337` |
|
||||
| `emitErrors` | Enable errors to be emitted to `koa` when they happen in order to attach custom logic or use error reporting services. | boolean | |
|
||||
| `url` | Url of the server. Enable proxy support such as Apache or Nginx, example: `https://mywebsite.com/api`. Default value: `http://${host}:${port}`. | string | |
|
||||
| `cron` | Cron configuration (powered by [`node-schedule`](https://github.com/node-schedule/node-schedule)) | Object | |
|
||||
| `cron.enabled` | Enable or disable CRON tasks to schedule jobs at specific dates. | boolean | `false` |
|
||||
| `admin` | Admin panel configuration | Object | |
|
||||
| `admin.url` | Url of your admin panel. Default value: `/admin`. Note: If the url is relative, it will be concatenated with `url`. | string | `/admin` |
|
||||
| `admin.autoOpen` | Enable or disabled administration opening on start. | boolean | `true` |
|
||||
| `admin.watchIgnoreFiles` | Add custom files that should not be watched during development. See more [here](https://github.com/paulmillr/chokidar#path-filtering) (property `ignored`). | Array(string) | `[]`. |
|
||||
| `admin.build` | Admin panel build configuration | Object | |
|
||||
| `admin.build.backend` | URL that the admin panel and plugins will request | string | |
|
||||
|
||||
## Functions
|
||||
|
||||
@ -103,7 +235,7 @@ CRON tasks allow you to schedule jobs (arbitrary functions) for execution at spe
|
||||
This feature is powered by [`node-schedule`](https://www.npmjs.com/package/node-schedule) node modules. Check it for more information.
|
||||
|
||||
::: warning
|
||||
Make sure the `enabled` cron config is set to `true` in `./config/environments/**/server.json` file.
|
||||
Make sure the `enabled` cron config is set to `true` in `./config/server.js` file.
|
||||
:::
|
||||
|
||||
The cron format consists of:
|
||||
@ -179,23 +311,13 @@ module.exports = (bookshelf, connection) => {
|
||||
|
||||
::::
|
||||
|
||||
## Environments
|
||||
|
||||
Most of the application's configurations are defined by environment. It means that you can specify settings for each environment (`development`, `production`, `test`, etc.).
|
||||
|
||||
To start your application in production environement you will have to specify `NODE_ENV=production`.
|
||||
|
||||
::: tip
|
||||
You can access the config of the current environment through `strapi.config.currentEnvironment`.
|
||||
:::
|
||||
|
||||
## Database
|
||||
|
||||
This file lets you define database connections that will be used to store your application content.
|
||||
|
||||
You can find [supported database and versions](../installation/cli.html#databases) in the local installation process.
|
||||
|
||||
**Path —** `./config/environments/**/database.json`.
|
||||
**Path —** `./config/database.js`.
|
||||
|
||||
:::: tabs
|
||||
|
||||
@ -255,270 +377,114 @@ You can find [supported database and versions](../installation/cli.html#database
|
||||
|
||||
#### Example
|
||||
|
||||
**Path —** `./config/environments/**/database.json`.
|
||||
**Path —** `./config/database.js`.
|
||||
|
||||
:::: tabs
|
||||
|
||||
::: tab Postgres
|
||||
|
||||
```json
|
||||
{
|
||||
"defaultConnection": "default",
|
||||
"connections": {
|
||||
"default": {
|
||||
"connector": "bookshelf",
|
||||
"settings": {
|
||||
"client": "postgres",
|
||||
"host": "localhost",
|
||||
"port": 5432,
|
||||
"username": "${process.env.USERNAME}",
|
||||
"password": "${process.env.PASSWORD}",
|
||||
"database": "strapi",
|
||||
"schema": "public"
|
||||
```js
|
||||
module.exports = ({ env }) => ({
|
||||
defaultConnection: 'default',
|
||||
connections: {
|
||||
default: {
|
||||
connector: 'bookshelf',
|
||||
settings: {
|
||||
client: 'postgres',
|
||||
host: env('DATABASE_HOST', 'localhost'),
|
||||
port: env.int('DATABASE_PORT', 5432),
|
||||
database: env('DATABASE_NAME', 'strapi'),
|
||||
username: env('DATABASE_USERNAME', 'strapi'),
|
||||
password: env('DATABASE_PASSWORD', 'strapi'),
|
||||
schema: 'public',
|
||||
},
|
||||
"options": {
|
||||
"debug": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
options: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
::: tab MySQL
|
||||
|
||||
```json
|
||||
{
|
||||
"defaultConnection": "default",
|
||||
"connections": {
|
||||
"default": {
|
||||
"connector": "bookshelf",
|
||||
"settings": {
|
||||
"client": "mysql",
|
||||
"host": "localhost",
|
||||
"port": 5432,
|
||||
"username": "strapi",
|
||||
"password": "root",
|
||||
"database": "strapi"
|
||||
```js
|
||||
module.exports = ({ env }) => ({
|
||||
defaultConnection: 'default',
|
||||
connections: {
|
||||
default: {
|
||||
connector: 'bookshelf',
|
||||
settings: {
|
||||
client: 'mysql',
|
||||
host: env('DATABASE_HOST', 'localhost'),
|
||||
port: env.int('DATABASE_PORT', 3306),
|
||||
database: env('DATABASE_NAME', 'strapi'),
|
||||
username: env('DATABASE_USERNAME', 'strapi'),
|
||||
password: env('DATABASE_PASSWORD', 'strapi'),
|
||||
},
|
||||
"options": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
options: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
::: tab SQLite
|
||||
|
||||
```json
|
||||
{
|
||||
"defaultConnection": "default",
|
||||
"connections": {
|
||||
"default": {
|
||||
"connector": "bookshelf",
|
||||
"settings": {
|
||||
"client": "sqlite",
|
||||
"filename": ".tmp/data.db"
|
||||
```js
|
||||
module.exports = ({ env }) => ({
|
||||
defaultConnection: 'default',
|
||||
connections: {
|
||||
default: {
|
||||
connector: 'bookshelf',
|
||||
settings: {
|
||||
client: 'sqlite',
|
||||
filename: env('DATABASE_FILENAME', '.tmp/data.db'),
|
||||
},
|
||||
"options": {
|
||||
"useNullAsDefault": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
options: {
|
||||
useNullAsDefault: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
::: tab Mongo
|
||||
|
||||
```json
|
||||
{
|
||||
"defaultConnection": "default",
|
||||
"connections": {
|
||||
"default": {
|
||||
"connector": "mongoose",
|
||||
"settings": {
|
||||
"client": "mongo",
|
||||
"host": "localhost",
|
||||
"port": 27017,
|
||||
"database": "strapi",
|
||||
"username": "",
|
||||
"password": ""
|
||||
```js
|
||||
module.exports = ({ env }) => ({
|
||||
defaultConnection: 'default',
|
||||
connections: {
|
||||
default: {
|
||||
connector: 'mongoose',
|
||||
settings: {
|
||||
client: 'mongo',
|
||||
host: env('DATABASE_HOST', 'localhost'),
|
||||
port: env.int('DATABASE_PORT', 27017),
|
||||
database: env('DATABASE_NAME', 'strapi'),
|
||||
username: env('DATABASE_USERNAME', 'strapi'),
|
||||
password: env('DATABASE_PASSWORD', 'strapi'),
|
||||
},
|
||||
"options": {
|
||||
"authenticationDatabase": "",
|
||||
"ssl": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
options: {
|
||||
authenticationDatabase: env('AUTHENTICATION_DATABASE'),
|
||||
ssl: env('DATABASE_SSL'),
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
::::
|
||||
|
||||
::: tip
|
||||
Please refer to the [dynamic configurations section](#dynamic-configurations) to use global environment variable to configure the databases.
|
||||
:::
|
||||
|
||||
::: tip
|
||||
Take a look at the [database's guide](../guides/databases.md) for more details.
|
||||
:::
|
||||
|
||||
## Request
|
||||
|
||||
**Path —** `./config/environments/**/request.json`.
|
||||
|
||||
- `session`
|
||||
- `enabled` (boolean): Enable or disable sessions. Default value: `false`.
|
||||
- `client` (string): Client used to persist sessions. Default value: `redis`.
|
||||
- `settings`
|
||||
- `host` (string): Client host name. Default value: `localhost`.
|
||||
- `port` (integer): Client port. Default value: `6379`.
|
||||
- `database`(integer)|String - Client database name. Default value: `10`.
|
||||
- `password` (string): Client password. Default value: ``.
|
||||
- `logger`
|
||||
- `level` (string): Default log level. Default value: `debug`.
|
||||
- `exposeInContext` (boolean): Expose logger in context so it can be used through `strapi.log.info(‘my log’)`. Default value: `true`.
|
||||
- `requests` (boolean): Enable or disable requests logs. Default value: `false`.
|
||||
- `parser`
|
||||
- `enabled`(boolean): Enable or disable parser. Default value: `true`.
|
||||
- `multipart` (boolean): Enable or disable multipart bodies parsing. Default value: `true`.
|
||||
|
||||
::: tip
|
||||
The session doesn't work with `mongo` as a client. The package that we should use is broken for now.
|
||||
:::
|
||||
|
||||
## Response
|
||||
|
||||
**Path —** `./config/environments/**/response.json`.
|
||||
|
||||
- [`gzip`](https://en.wikipedia.org/wiki/Gzip)
|
||||
- `enabled` (boolean): Enable or not GZIP response compression.
|
||||
- `responseTime`
|
||||
- `enabled` (boolean): Enable or not `X-Response-Time header` to response. Default value: `false`.
|
||||
- `poweredBy`
|
||||
- `enabled` (boolean): Enable or not `X-Powered-By` header to response. Default value: `true`.
|
||||
- `value` (string): The value of the header. Default value: `Strapi <strapi.io>`
|
||||
|
||||
## Security
|
||||
|
||||
**Path —** `./config/environments/**/security.json`.
|
||||
|
||||
- [`csp`](https://en.wikipedia.org/wiki/Content_Security_Policy)
|
||||
- `enabled` (boolean): Enable or disable CSP to avoid Cross Site Scripting (XSS) and data injection attacks.
|
||||
- [`p3p`](https://en.wikipedia.org/wiki/P3P)
|
||||
- `enabled` (boolean): Enable or disable p3p.
|
||||
- [`hsts`](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security)
|
||||
- `enabled` (boolean): Enable or disable HSTS.
|
||||
- `maxAge` (integer): Number of seconds HSTS is in effect. Default value: `31536000`.
|
||||
- `includeSubDomains` (boolean): Applies HSTS to all subdomains of the host. Default value: `true`.
|
||||
- [`xframe`](https://en.wikipedia.org/wiki/Clickjacking)
|
||||
- `enabled` (boolean): Enable or disable `X-FRAME-OPTIONS` headers in response.
|
||||
- `value` (string): The value for the header, e.g. DENY, SAMEORIGIN or ALLOW-FROM uri. Default value: `SAMEORIGIN`.
|
||||
- [`xss`](https://en.wikipedia.org/wiki/Cross-site_scripting)
|
||||
- `enabled` (boolean): Enable or disable XSS to prevent Cross Site Scripting (XSS) attacks in older IE browsers (IE8).
|
||||
- [`cors`](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing)
|
||||
- `enabled` (boolean): Enable or disable CORS to prevent your server to be requested from another domain.
|
||||
- `origin` (string): Allowed URLs (`http://example1.com, http://example2.com` or allows everyone `*`). Default value: `http://localhost`.
|
||||
- `expose` (array): Configures the `Access-Control-Expose-Headers` CORS header. If not specified, no custom headers are exposed. Default value: `["WWW-Authenticate", "Server-Authorization"]`.
|
||||
- `maxAge` (integer): Configures the `Access-Control-Max-Age` CORS header. Default value: `31536000`.
|
||||
- `credentials` (boolean): Configures the `Access-Control-Allow-Credentials` CORS header. Default value: `true`.
|
||||
- `methods` (array)|String - Configures the `Access-Control-Allow-Methods` CORS header. Default value: `["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"]`.
|
||||
- `headers` (array): Configures the `Access-Control-Allow-Headers` CORS header. If not specified, defaults to reflecting the headers specified in the request's Access-Control-Request-Headers header. Default value: `["Content-Type", "Authorization", "X-Frame-Options"]`.
|
||||
- `ip`
|
||||
- `enabled` (boolean): Enable or disable IP blocker. Default value: `false`.
|
||||
- `whiteList` (array): Whitelisted IPs. Default value: `[]`.
|
||||
- `blackList` (array): Blacklisted IPs. Default value: `[]`.
|
||||
|
||||
## Server
|
||||
|
||||
**Path —** `./config/environments/**/server.json`.
|
||||
|
||||
- `host` (string): Host name. Default value: `localhost`.
|
||||
- `port` (integer): Port on which the server should be running. Default value: `1337`.
|
||||
- `emitErrors` (boolean): Enable errors to be emitted to `koa` when they happen in order to attach custom logic or use error reporting services.
|
||||
- `proxy`
|
||||
- `enabled` (boolean): Enable proxy support such as Apache or Nginx. Default value: `false`.
|
||||
- `ssl` (boolean): Enable proxy SSL support.
|
||||
- `host` (string): Host name your proxy service uses for Strapi.
|
||||
- `port` (integer): Port that your proxy service accepts connections on.
|
||||
- [`cron`](https://en.wikipedia.org/wiki/Cron)
|
||||
- `enabled` (boolean): Enable or disable CRON tasks to schedule jobs at specific dates. Default value: `false`.
|
||||
- `admin`
|
||||
- `autoOpen` (boolean): Enable or disabled administration opening on start. Default value: `true`.
|
||||
- `path` (string): Allow to change the URL to access the admin panel. Default value: `/admin`.
|
||||
- `watchIgnoreFiles` (array): Add custom files that should not be watched during development. See more [here](https://github.com/paulmillr/chokidar#path-filtering) (property `ignored`). Default value: `[]`.
|
||||
- `build`
|
||||
- `backend` (string): URL that the admin panel and plugins will request (default: `http://localhost:1337`).
|
||||
|
||||
#### Example
|
||||
|
||||
**Path —** `./config/environments/**/server.json`.
|
||||
|
||||
As an example using this configuration with Nginx your server would respond to `https://example.com:8443` instead of `http://localhost:1337`.
|
||||
|
||||
**Note:** you will need to configure Nginx or Apache as a proxy before configuring this example.
|
||||
|
||||
```json
|
||||
{
|
||||
"host": "localhost",
|
||||
"port": 1337,
|
||||
"proxy": {
|
||||
"enabled": true,
|
||||
"ssl": true,
|
||||
"host": "example.com",
|
||||
"port": 8443
|
||||
},
|
||||
"cron": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Dynamic configurations
|
||||
|
||||
For security reasons, sometimes it's better to set variables through the server environment. It's also useful to push dynamic values into configuration files. To enable this feature in JSON files, Strapi embraces a JSON-file interpreter into its core to allow dynamic values in the JSON configuration files.
|
||||
|
||||
### Syntax
|
||||
|
||||
The syntax is inspired by the [template literals ES2015 specifications](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals). These dynamic values are indicated by the Dollar sign and curly braces (`${expression}`).
|
||||
|
||||
### Usage
|
||||
|
||||
In any JSON configuration file in your project, you can inject dynamic values like this:
|
||||
|
||||
**Path —** `./config/environments/production/database.json`.
|
||||
|
||||
```json
|
||||
{
|
||||
"defaultConnection": "default",
|
||||
"connections": {
|
||||
"default": {
|
||||
"connector": "mongoose",
|
||||
"settings": {
|
||||
"client": "mongo",
|
||||
"uri": "${process.env.DATABASE_URI || ''}",
|
||||
"host": "${process.env.DATABASE_HOST || '127.0.0.1'}",
|
||||
"port": "${process.env.DATABASE_PORT || 27017}",
|
||||
"database": "${process.env.DATABASE_NAME || 'production'}",
|
||||
"username": "${process.env.DATABASE_USERNAME || ''}",
|
||||
"password": "${process.env.DATABASE_PASSWORD || ''}"
|
||||
},
|
||||
"options": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
::: tip
|
||||
You can't execute functions inside the curly braces. Only strings are allowed.
|
||||
:::
|
||||
|
||||
## Configuration in database
|
||||
|
||||
Configuration files are not multi server friendly. So we created a data store for config you will want to update in production.
|
||||
|
||||
@ -12,27 +12,13 @@ By default, your project's structure will look like this:
|
||||
- [`/services`](./services.md): contains the API's custom services.
|
||||
- `/build`: contains your admin panel UI build.
|
||||
- [`/config`](./configurations.md)
|
||||
- [`/environments`](./configurations.md#environments): contains the project's configurations per environment.
|
||||
- `/**`
|
||||
- `/development`
|
||||
- [`custom.json`](./configurations.md#custom): contains the custom configurations for this environment.
|
||||
- [`database.json`](./configurations.md#database): contains the database connections for this environment.
|
||||
- [`request.json`](./configurations.md#request): contains the request settings for this environment.
|
||||
- [`response.json`](./configurations.md#response): contains the response settings for this environment.
|
||||
- [`security.json`](./configurations.md#security): contains the security settings for this environment.
|
||||
- [`server.json`](./configurations.md#server): contains the server settings for this environment.
|
||||
- `/production`
|
||||
- `/staging`
|
||||
- [`/functions`](./configurations.md#functions): contains lifecycle or generic functions of the project.
|
||||
- [`/responses`](./configurations.md#responses): contains custom responses.
|
||||
- [`404.js`](./configurations.md#404): contains a template for constructing your custom 404 message.
|
||||
- [`bootstrap.js`](./configurations.md#bootstrap): contains the code executed at the application start.
|
||||
- [`cron.js`](./configurations.md#cron-tasks): contains the cron tasks.
|
||||
- [`application.json`](./configurations.md#application): contains the general configurations of the project.
|
||||
- [`custom.json`](./configurations.md#custom): contains the custom configurations of the project.
|
||||
- [`hook.json`](./configurations.md#hook): contains the hook settings of the project.
|
||||
- [`language.json`](./configurations.md#language): contains the language settings of the project.
|
||||
- [`middleware.json`](./configurations.md#middleware): contains the middleware settings of the project.
|
||||
- [`server.js`](./configurations.md#server): contains the general configurations of the project.
|
||||
- [`database.js`](./configurations.md#database): contains the database configurations of the project.
|
||||
- [`/extensions`](./customization.md): contains the files to extend installed plugins.
|
||||
- [`/hooks`](./hooks.md): contains the custom hooks of the project.
|
||||
- [`/middlewares`](./middlewares.md): contains the custom middlewares of the project.
|
||||
|
||||
@ -77,14 +77,14 @@ The framework allows to load hooks from the project directly without having to i
|
||||
|
||||
## Configuration and activation
|
||||
|
||||
To activate and configure your hook with custom options, you need to edit your `./config/environments/**/hook.json` file in your Strapi app.
|
||||
To activate and configure your hook with custom options, you need to edit your `./config/hook.js` file in your Strapi app.
|
||||
|
||||
```javascript
|
||||
{
|
||||
...
|
||||
"hook-name": {
|
||||
"enabled": true,
|
||||
...
|
||||
}
|
||||
}
|
||||
```js
|
||||
module.exports = {
|
||||
settings: {
|
||||
'hook-name': {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
@ -67,21 +67,19 @@ Every middleware will be injected into the Koa stack. To manage the load order,
|
||||
|
||||
## Configuration and activation
|
||||
|
||||
To activate and configure your hook with custom options, you need to edit your `./config/environments/**/middleware.json` file in your Strapi app.
|
||||
To configure the middlewares of your application, you need to create or edit the `./config/middleware.js` file in your Strapi app.
|
||||
|
||||
By default this file doesn't exist, you will have to create it.
|
||||
|
||||
```javascript
|
||||
{
|
||||
...
|
||||
"middleware-name": {
|
||||
"enabled": true,
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
||||
**Availabe options**
|
||||
|
||||
## Core middlewares
|
||||
- `timeout` (integer): Defines the maximum allowed milliseconds to load a middleware.
|
||||
- `load` (Object): Configuration middleware loading. See details [here](#load-order)
|
||||
- `settings` (Object): Configuration of each middleware
|
||||
- `{middlewareName}` (Object): Configuration of one middleware
|
||||
- `enabled` (boolean): Tells Strapi to run the middleware or not
|
||||
|
||||
## Core middleware configurations
|
||||
|
||||
The core of Strapi embraces a small list of middlewares for performances, security and great error handling.
|
||||
|
||||
@ -109,26 +107,109 @@ The core of Strapi embraces a small list of middlewares for performances, securi
|
||||
The following middlewares cannot be disabled: responses, router, logger and boom.
|
||||
:::
|
||||
|
||||
### Load order
|
||||
### Global middlewares
|
||||
|
||||
The middlewares are injected into the Koa stack asynchronously. Sometimes it happens that some of these middlewares need to be loaded in a specific order. To define a load order, we created a dedicated file located in `./config/middleware.json`.
|
||||
- `favicon`
|
||||
- `path` (string): Path to the favicon file. Default value: `favicon.ico`.
|
||||
- `maxAge` (integer): Cache-control max-age directive in ms. Default value: `86400000`.
|
||||
- `public`
|
||||
- `path` (string): Path to the public folder. Default value: `./public`.
|
||||
- `maxAge` (integer): Cache-control max-age directive in ms. Default value: `60000`.
|
||||
- `defaultIndex` (boolean): Display default index page at `/` and `/index.html`. Default value: `true`.
|
||||
|
||||
**Path —** `./config/middleware.json`.
|
||||
### Request middlewares
|
||||
|
||||
```json
|
||||
{
|
||||
"timeout": 100,
|
||||
"load": {
|
||||
"before": ["responseTime", "logger", "cors", "responses"],
|
||||
"order": [
|
||||
"Define the middlewares' load order by putting their name in this array in the right order"
|
||||
],
|
||||
"after": ["parser", "router"]
|
||||
}
|
||||
}
|
||||
- `session`
|
||||
- `enabled` (boolean): Enable or disable sessions. Default value: `false`.
|
||||
- `client` (string): Client used to persist sessions. Default value: `redis`.
|
||||
- `settings`
|
||||
- `host` (string): Client host name. Default value: `localhost`.
|
||||
- `port` (integer): Client port. Default value: `6379`.
|
||||
- `database`(integer)|String - Client database name. Default value: `10`.
|
||||
- `password` (string): Client password. Default value: ``.
|
||||
- `logger`
|
||||
- `level` (string): Default log level. Default value: `debug`.
|
||||
- `exposeInContext` (boolean): Expose logger in context so it can be used through `strapi.log.info(‘my log’)`. Default value: `true`.
|
||||
- `requests` (boolean): Enable or disable requests logs. Default value: `false`.
|
||||
- `parser`
|
||||
- `enabled`(boolean): Enable or disable parser. Default value: `true`.
|
||||
- `multipart` (boolean): Enable or disable multipart bodies parsing. Default value: `true`.
|
||||
|
||||
::: tip
|
||||
The session doesn't work with `mongo` as a client. The package that we should use is broken for now.
|
||||
:::
|
||||
|
||||
## Response middlewares
|
||||
|
||||
- [`gzip`](https://en.wikipedia.org/wiki/Gzip)
|
||||
- `enabled` (boolean): Enable or not GZIP response compression.
|
||||
- `responseTime`
|
||||
- `enabled` (boolean): Enable or not `X-Response-Time header` to response. Default value: `false`.
|
||||
- `poweredBy`
|
||||
- `enabled` (boolean): Enable or not `X-Powered-By` header to response. Default value: `true`.
|
||||
- `value` (string): The value of the header. Default value: `Strapi <strapi.io>`
|
||||
|
||||
### Security middlewares
|
||||
|
||||
- [`csp`](https://en.wikipedia.org/wiki/Content_Security_Policy)
|
||||
- `enabled` (boolean): Enable or disable CSP to avoid Cross Site Scripting (XSS) and data injection attacks.
|
||||
- [`p3p`](https://en.wikipedia.org/wiki/P3P)
|
||||
- `enabled` (boolean): Enable or disable p3p.
|
||||
- [`hsts`](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security)
|
||||
- `enabled` (boolean): Enable or disable HSTS.
|
||||
- `maxAge` (integer): Number of seconds HSTS is in effect. Default value: `31536000`.
|
||||
- `includeSubDomains` (boolean): Applies HSTS to all subdomains of the host. Default value: `true`.
|
||||
- [`xframe`](https://en.wikipedia.org/wiki/Clickjacking)
|
||||
- `enabled` (boolean): Enable or disable `X-FRAME-OPTIONS` headers in response.
|
||||
- `value` (string): The value for the header, e.g. DENY, SAMEORIGIN or ALLOW-FROM uri. Default value: `SAMEORIGIN`.
|
||||
- [`xss`](https://en.wikipedia.org/wiki/Cross-site_scripting)
|
||||
- `enabled` (boolean): Enable or disable XSS to prevent Cross Site Scripting (XSS) attacks in older IE browsers (IE8).
|
||||
- [`cors`](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing)
|
||||
- `enabled` (boolean): Enable or disable CORS to prevent your server to be requested from another domain.
|
||||
- `origin` (string): Allowed URLs (`http://example1.com, http://example2.com` or allows everyone `*`). Default value: `*`.
|
||||
- `expose` (array): Configures the `Access-Control-Expose-Headers` CORS header. If not specified, no custom headers are exposed. Default value: `["WWW-Authenticate", "Server-Authorization"]`.
|
||||
- `maxAge` (integer): Configures the `Access-Control-Max-Age` CORS header. Default value: `31536000`.
|
||||
- `credentials` (boolean): Configures the `Access-Control-Allow-Credentials` CORS header. Default value: `true`.
|
||||
- `methods` (array)|String - Configures the `Access-Control-Allow-Methods` CORS header. Default value: `["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"]`.
|
||||
- `headers` (array): Configures the `Access-Control-Allow-Headers` CORS header. If not specified, defaults to reflecting the headers specified in the request's Access-Control-Request-Headers header. Default value: `["Content-Type", "Authorization", "X-Frame-Options"]`.
|
||||
- `ip`
|
||||
- `enabled` (boolean): Enable or disable IP blocker. Default value: `false`.
|
||||
- `whiteList` (array): Whitelisted IPs. Default value: `[]`.
|
||||
- `blackList` (array): Blacklisted IPs. Default value: `[]`.
|
||||
|
||||
**Example**:
|
||||
|
||||
**Path —** `./config/middleware.js`.
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
//...
|
||||
settings: {
|
||||
cors: {
|
||||
origin: 'http://localhost',
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### Load order
|
||||
|
||||
The middlewares are injected into the Koa stack asynchronously. Sometimes it happens that some of these middlewares need to be loaded in a specific order. To define a load order, create or edit the file `./config/middleware.js`.
|
||||
|
||||
**Path —** `./config/middleware.js`.
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
load: {
|
||||
before: ['responseTime', 'logger', 'cors', 'responses'],
|
||||
order: [
|
||||
"Define the middlewares' load order by putting their name in this array in the right order",
|
||||
],
|
||||
after: ['parser', 'router'],
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
- `timeout`: Defines the maximum allowed milliseconds to load a middleware.
|
||||
- `load`:
|
||||
- `before`: Array of middlewares that need to be loaded in the first place. The order of this array matters.
|
||||
- `order`: Array of middlewares that need to be loaded in a specific order.
|
||||
@ -160,29 +241,23 @@ module.exports = strapi => {
|
||||
|
||||
Enable the middleware in environments settings.
|
||||
|
||||
**Path —** `config/environments/**/middleware.json`.
|
||||
|
||||
```json
|
||||
{
|
||||
"timer": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Load a middleware at the very first place
|
||||
|
||||
**Path —** `./config/middleware.json`
|
||||
**Path —** `./config/middleware.js`
|
||||
|
||||
```json
|
||||
{
|
||||
"timeout": 100,
|
||||
"load": {
|
||||
"before": ["time", "responseTime", "logger", "cors", "responses", "gzip"],
|
||||
"order": [
|
||||
"Define the middlewares' load order by putting their name in this array is the right order"
|
||||
```js
|
||||
module.exports = {
|
||||
load: {
|
||||
before: ['timer', 'responseTime', 'logger', 'cors', 'responses', 'gzip'],
|
||||
order: [
|
||||
"Define the middlewares' load order by putting their name in this array is the right order",
|
||||
],
|
||||
"after": ["parser", "router"]
|
||||
}
|
||||
}
|
||||
after: ['parser', 'router'],
|
||||
},
|
||||
settings: {
|
||||
timer: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
@ -4,21 +4,18 @@
|
||||
|
||||
### Content Type's models
|
||||
|
||||
Models are a representation of the database's structure and life cycle. They are split into two separate files. A JavaScript file that contains the life cycle callbacks, and a JSON one that represents the data stored in the database and their format. The models also allow you to define the relationships between them.
|
||||
Models are a representation of the database's structure. They are split into two separate files. A JavaScript file that contains the model options (e.g: lifecycle hooks), and a JSON one that represents the data structure stored in the database.
|
||||
|
||||
**Path —** `./api/restaurant/models/Restaurant.js`.
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
// Before saving a value.
|
||||
// Fired before an `insert` or `update` query.
|
||||
beforeSave: (model, attrs, options) => {},
|
||||
|
||||
// After saving a value.
|
||||
// Fired after an `insert` or `update` query.
|
||||
afterSave: (model, attrs, options) => {},
|
||||
|
||||
// ... and more
|
||||
lifecycles: {
|
||||
// Called before an entry is created
|
||||
beforeCreate(data) {},
|
||||
// Called after an entry is created
|
||||
afterCreated(result) {},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
@ -130,7 +127,7 @@ Additional settings can be set on models:
|
||||
}
|
||||
```
|
||||
|
||||
In this example, the model `Restaurant` will be accessible through the `Restaurants` global variable. The data will be stored in the `Restaurants_v1` collection or table and the model will use the `mongo` connection defined in `./config/environments/**/database.json`
|
||||
In this example, the model `Restaurant` will be accessible through the `Restaurants` global variable. The data will be stored in the `Restaurants_v1` collection or table and the model will use the `mongo` connection defined in `./config/database.js`
|
||||
|
||||
::: warning
|
||||
If not set manually in the JSON file, Strapi will adopt the filename as `globalId`.
|
||||
@ -341,7 +338,7 @@ xhr.send(
|
||||
|
||||
::: tab "One-to-Many" id="one-to-many"
|
||||
|
||||
One-to-Many relationships are useful when an entry can be liked to multiple entries of another Content Type. And an entry of the other Content Type can be linked to only one entry.
|
||||
One-to-Many relationships are useful when an entry can be linked to multiple entries of another Content Type. And an entry of the other Content Type can be linked to only one entry.
|
||||
|
||||
#### Example
|
||||
|
||||
@ -400,7 +397,7 @@ xhr.send(
|
||||
|
||||
::: tab "Many-to-Many" id="many-to-many"
|
||||
|
||||
Many-to-Many relationships are useful when an entry can be liked to multiple entries of another Content Type. And an entry of the other Content Type can be linked to many entries.
|
||||
Many-to-Many relationships are useful when an entry can be linked to multiple entries of another Content Type. And an entry of the other Content Type can be linked to many entries.
|
||||
|
||||
#### Example
|
||||
|
||||
@ -894,69 +891,203 @@ xhr.send(
|
||||
|
||||
::::
|
||||
|
||||
## Life cycle callbacks
|
||||
## Lifecycle hooks
|
||||
|
||||
::: warning
|
||||
The life cycle functions are based on the ORM life cycle and not on the Strapi request.
|
||||
We are currently working on it to make it easier to use and understand.
|
||||
Please check [this issue](https://github.com/strapi/strapi/issues/1443) on GitHub.
|
||||
:::
|
||||
The lifecycle hooks are functions that get triggered when the Strapi [`queries`](../concepts/queries.md) are called. They will get triggered automatically when you manage your content in the Admin Panel or when you develop custom code using `queries`·
|
||||
|
||||
The following events are available by default:
|
||||
To configure a `ContentType` lifecycle hooks you can set a `lifecycles` key in the `{modelName}.js` file located at `./api/{apiName}/models/{modelName}.js` folder.
|
||||
|
||||
Callbacks on:
|
||||
### Available Lifecycle hooks
|
||||
|
||||
:::: tabs
|
||||
|
||||
::: tab save
|
||||
::: tab find
|
||||
|
||||
`save`
|
||||
**`beforeFind(params, populate)`**
|
||||
|
||||
- beforeSave
|
||||
- afterSave
|
||||
_Parameters:_
|
||||
|
||||
| Name | Type | Description |
|
||||
| ------ | ------ | ----------------------------------- |
|
||||
| params | Object | Find params _(e.g: limit, filters)_ |
|
||||
|
||||
---
|
||||
|
||||
**`afterFind(results, params, populate)`**
|
||||
|
||||
_Parameters:_
|
||||
|
||||
| Name | Type | Description |
|
||||
| -------- | ------------- | -------------------------------------- |
|
||||
| results | Array{Object} | The results found for the `find` query |
|
||||
| params | Object | Find params _(e.g: limit, filters)_ |
|
||||
| populate | Array{string} | Populate specific relations |
|
||||
|
||||
:::
|
||||
|
||||
::: tab fetch
|
||||
::: tab findOne
|
||||
|
||||
`fetch`
|
||||
**`beforeFindOne(params, populate)`**
|
||||
|
||||
- beforeFetch
|
||||
- afterFetch
|
||||
_Parameters:_
|
||||
|
||||
::: tab fetchAll
|
||||
| Name | Type | Description |
|
||||
| ------ | ------ | ---------------------------- |
|
||||
| params | Object | Find params _(e.g: filters)_ |
|
||||
|
||||
`fetchAll`
|
||||
---
|
||||
|
||||
- beforeFetchAll
|
||||
- afterFetchAll
|
||||
**`afterFindOne(result, params, populate)`**
|
||||
|
||||
_Parameters:_
|
||||
|
||||
| Name | Type | Description |
|
||||
| -------- | ------------- | ----------------------------------------- |
|
||||
| result | Object | The results found for the `findOne` query |
|
||||
| params | Object | Find params _(e.g: filters)_ |
|
||||
| populate | Array{string} | Populate specific relations |
|
||||
|
||||
:::
|
||||
|
||||
::: tab create
|
||||
|
||||
`create`
|
||||
**`beforeCreate(data)`**
|
||||
|
||||
- beforeCreate
|
||||
- afterCreate
|
||||
_Parameters:_
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ------ | ---------------------------------------- |
|
||||
| data | Object | Input data to the entry was created with |
|
||||
|
||||
---
|
||||
|
||||
**`afterCreate(result, data)`**
|
||||
|
||||
_Parameters:_
|
||||
|
||||
| Name | Type | Description |
|
||||
| ------ | ------ | ---------------------------------------- |
|
||||
| result | Object | Created entry |
|
||||
| data | Object | Input data to the entry was created with |
|
||||
|
||||
:::
|
||||
|
||||
::: tab update
|
||||
|
||||
`update`
|
||||
**`beforeUpdate(params, data)`**
|
||||
|
||||
- beforeUpdate
|
||||
- afterUpdate
|
||||
_Parameters:_
|
||||
|
||||
| Name | Type | Description |
|
||||
| ------ | ------ | ---------------------------------------- |
|
||||
| params | Object | Find params _(e.g: filters)_ |
|
||||
| data | Object | Input data to the entry was created with |
|
||||
|
||||
---
|
||||
|
||||
**`afterUpdate(result, params, data)`**
|
||||
|
||||
_Parameters:_
|
||||
|
||||
| Name | Type | Description |
|
||||
| ------ | ------ | ---------------------------------------- |
|
||||
| result | Object | Updated entry |
|
||||
| params | Object | Find params _(e.g: filters)_ |
|
||||
| data | Object | Input data to the entry was created with |
|
||||
|
||||
:::
|
||||
|
||||
::: tab destroy
|
||||
::: tab delete
|
||||
|
||||
`destroy`
|
||||
**`beforeDeleted(params)`**
|
||||
|
||||
- beforeDestroy
|
||||
- afterDestroy
|
||||
_Parameters:_
|
||||
|
||||
| Name | Type | Description |
|
||||
| ------ | ------ | ---------------------------- |
|
||||
| params | Object | Find params _(e.g: filters)_ |
|
||||
|
||||
---
|
||||
|
||||
**`afterDeleted(result, params)`**
|
||||
|
||||
_Parameters:_
|
||||
|
||||
| Name | Type | Description |
|
||||
| ------ | ------ | ---------------------------- |
|
||||
| result | Object | Deleted entry |
|
||||
| params | Object | Find params _(e.g: filters)_ |
|
||||
|
||||
:::
|
||||
|
||||
::: tab count
|
||||
|
||||
**`beforeCount(params)`**
|
||||
|
||||
_Parameters:_
|
||||
|
||||
| Name | Type | Description |
|
||||
| ------ | ------ | ---------------------------- |
|
||||
| params | Object | Find params _(e.g: filters)_ |
|
||||
|
||||
---
|
||||
|
||||
**`afterCount(result, params)`**
|
||||
|
||||
_Parameters:_
|
||||
|
||||
| Name | Type | Description |
|
||||
| ------ | ------- | ---------------------------- |
|
||||
| result | Integer | The count matching entries |
|
||||
| params | Object | Find params _(e.g: filters)_ |
|
||||
|
||||
:::
|
||||
|
||||
::: tab search
|
||||
|
||||
**`beforeSearch(params, populate)`**
|
||||
|
||||
_Parameters:_
|
||||
|
||||
| Name | Type | Description |
|
||||
| -------- | ------------- | ---------------------------- |
|
||||
| params | Object | Find params _(e.g: filters)_ |
|
||||
| populate | Array{string} | Populate specific relations |
|
||||
|
||||
---
|
||||
|
||||
**`afterSearch(result, params)`**
|
||||
|
||||
_Parameters:_
|
||||
|
||||
| Name | Type | Description |
|
||||
| -------- | ------------- | ---------------------------- |
|
||||
| results | Array{Object} | The entries found |
|
||||
| params | Object | Find params _(e.g: filters)_ |
|
||||
| populate | Array{string} | Populate specific relations |
|
||||
|
||||
:::
|
||||
|
||||
::: tab countSearch
|
||||
|
||||
**`beforeCountSearch(params)`**
|
||||
|
||||
_Parameters:_
|
||||
|
||||
| Name | Type | Description |
|
||||
| ------ | ------ | ---------------------------- |
|
||||
| params | Object | Find params _(e.g: filters)_ |
|
||||
|
||||
---
|
||||
|
||||
**`afterCountSearch(result, params)`**
|
||||
|
||||
_Parameters:_
|
||||
|
||||
| Name | Type | Description |
|
||||
| ------ | ------- | ---------------------------- |
|
||||
| result | Integer | The count matching entries |
|
||||
| params | Object | Find params _(e.g: filters)_ |
|
||||
|
||||
:::
|
||||
|
||||
@ -964,14 +1095,6 @@ Callbacks on:
|
||||
|
||||
### Example
|
||||
|
||||
:::: tabs
|
||||
|
||||
::: tab Mongoose
|
||||
|
||||
#### Mongoose
|
||||
|
||||
The entry is available through the `model` parameter.
|
||||
|
||||
**Path —** `./api/user/models/User.js`.
|
||||
|
||||
```js
|
||||
@ -979,43 +1102,68 @@ module.exports = {
|
||||
/**
|
||||
* Triggered before user creation.
|
||||
*/
|
||||
beforeCreate: async model => {
|
||||
// Hash password.
|
||||
const passwordHashed = await strapi.api.user.services.user.hashPassword(model.password);
|
||||
|
||||
// Set the password.
|
||||
model.password = passwordHashed;
|
||||
lifecycles: {
|
||||
async beforeCreate(data) {
|
||||
const passwordHashed = await strapi.api.user.services.user.hashPassword(data.password);
|
||||
data.password = passwordHashed;
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
:::
|
||||
::: tip
|
||||
You can mutate one of the parameters to change its properties. Make sure not to reassign the parameter as it will have no effect:
|
||||
|
||||
::: tab Bookshelf
|
||||
|
||||
#### Bookshelf
|
||||
|
||||
Each of these functions receives three parameters `model`, `attrs` and `options`. You have to return a Promise.
|
||||
|
||||
**Path —** `./api/user/models/User.js`.
|
||||
**This will Work**
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
/**
|
||||
* Triggered before user creation.
|
||||
*/
|
||||
beforeCreate: async (model, attrs, options) => {
|
||||
// Hash password.
|
||||
const passwordHashed = await strapi.api.user.services.user.hashPassword(
|
||||
model.attributes.password
|
||||
);
|
||||
lifecycles: {
|
||||
beforeCreate(data) {
|
||||
data.name = 'Some fixed name';
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
// Set the password.
|
||||
model.set('password', passwordHashed);
|
||||
**This will NOT Work**
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
lifecycles: {
|
||||
beforeCreate(data) {
|
||||
data = {
|
||||
...data,
|
||||
name: 'Some fixed name',
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
:::::
|
||||
### Custom use
|
||||
|
||||
When you are building custom ORM specific queries the lifecycles will not be triggered. You can however call a lifecycle function directly if you wish.
|
||||
|
||||
**Bookshelf example**
|
||||
|
||||
**Path -** `./api/{apiName}/services/{serviceName}.js`
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
async createCustomEntry() {
|
||||
const ORMModel = strapi.query(modelName).model;
|
||||
|
||||
const newCustomEntry = await ORMModel.forge().save();
|
||||
|
||||
// trigger manually
|
||||
ORMModel.lifecycles.afterCreate(newCustomEntry.toJSON());
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
::: tip
|
||||
When calling a lifecycle function directly, you will need to make sur you call it with the expected parameters.
|
||||
:::
|
||||
|
||||
@ -125,7 +125,7 @@ module.exports = async (ctx, next) => {
|
||||
|
||||
The policy `isAdmin` located in `./api/restaurant/config/policies/isAdmin.js` will be executed before the `find` action in the `Restaurant.js` controller.
|
||||
|
||||
### Using a policy outside it's api
|
||||
### Using a policy outside its api
|
||||
|
||||
To use a policy in another api you can reference it with the following syntax: `{apiName}.{policyName}`.
|
||||
|
||||
|
||||
@ -211,21 +211,21 @@ This event is triggered only when you delete a media through the media interface
|
||||
|
||||
### Available configurations
|
||||
|
||||
You can set webhook configurations inside the file `./config/environments/{env}/server.json`.
|
||||
You can set webhook configurations inside the file `./config/server.js`.
|
||||
|
||||
- `webhooks`
|
||||
- `defaultHeaders`: You can set default headers to use for your webhook requests. This option is overwritten by the headers set in the webhook itself.
|
||||
|
||||
**Example configuration**
|
||||
|
||||
```json
|
||||
{
|
||||
"webhooks": {
|
||||
"defaultHeaders": {
|
||||
"Custom-Header": "my-custom-header"
|
||||
}
|
||||
}
|
||||
}
|
||||
```js
|
||||
module.exports = {
|
||||
webhooks: {
|
||||
defaultHeaders: {
|
||||
'Custom-Header': 'my-custom-header',
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### Securing your webhooks
|
||||
@ -235,34 +235,34 @@ Most of the time, webhooks make requests to public URLs, therefore it is possibl
|
||||
To prevent this from happening you can send a header with an authentication token. Using the Admin panel you would have to do it for every webhook.
|
||||
Another way is to define `defaultHeaders` to add to every webhook requests.
|
||||
|
||||
You can configure these global headers by updating the file at `./config/environments/{env}/server.json`:
|
||||
You can configure these global headers by updating the file at `./config/server.js`:
|
||||
|
||||
:::: tabs
|
||||
|
||||
::: tab "Simple token"
|
||||
|
||||
```json
|
||||
{
|
||||
"webhooks": {
|
||||
"defaultHeaders": {
|
||||
"Authorization": "Bearer my-very-secured-token"
|
||||
}
|
||||
}
|
||||
}
|
||||
```js
|
||||
module.exports = {
|
||||
webhooks: {
|
||||
defaultHeaders: {
|
||||
Authorization: 'Bearer my-very-secured-token',
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
::: tab "Environment variable"
|
||||
|
||||
```json
|
||||
{
|
||||
"webhooks": {
|
||||
"defaultHeaders": {
|
||||
"Authorization": "Bearer ${ process.env.WEBHOOK_TOKEN }"
|
||||
}
|
||||
}
|
||||
}
|
||||
```js
|
||||
module.exports = {
|
||||
webhooks: {
|
||||
defaultHeaders: {
|
||||
Authorization: `Bearer ${process.env.WEBHOOK_TOKEN}`,
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
::::
|
||||
|
||||
@ -211,7 +211,7 @@ Strapi currently supports `Node.js v12.x.x`. The following steps will install No
|
||||
|
||||
```bash
|
||||
cd ~
|
||||
curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
|
||||
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
|
||||
...
|
||||
sudo apt-get install nodejs
|
||||
...
|
||||
@ -295,32 +295,32 @@ On your development machine, navigate to your Strapi project root directory:
|
||||
npm install pg
|
||||
```
|
||||
|
||||
#### 2. Edit the `database.json` file.
|
||||
#### 2. Edit the `./config/database.js` file.
|
||||
|
||||
Copy/paste the following:
|
||||
|
||||
`Path: ./my-project/config/environments/production/database.json`:
|
||||
`Path: ./my-project/config/database.js`:
|
||||
|
||||
```json
|
||||
{
|
||||
"defaultConnection": "default",
|
||||
"connections": {
|
||||
"default": {
|
||||
"connector": "bookshelf",
|
||||
"settings": {
|
||||
"client": "postgres",
|
||||
"host": "${process.env.DATABASE_HOST || '127.0.0.1'}",
|
||||
"port": "${process.env.DATABASE_PORT || 27017}",
|
||||
"database": "${process.env.DATABASE_NAME || 'strapi'}",
|
||||
"username": "${process.env.DATABASE_USERNAME || ''}",
|
||||
"password": "${process.env.DATABASE_PASSWORD || ''}"
|
||||
```js
|
||||
module.exports = ({ env }) => ({
|
||||
defaultConnection: 'default',
|
||||
connections: {
|
||||
default: {
|
||||
connector: 'bookshelf',
|
||||
settings: {
|
||||
client: 'postgres',
|
||||
host: env('DATABASE_HOST', '127.0.0.1'),
|
||||
port: env.int('DATABASE_PORT', 5432),
|
||||
database: env('DATABASE_NAME', 'strapi'),
|
||||
username: env('DATABASE_USERNAME', ''),
|
||||
password: env('DATABASE_PASSWORD', ''),
|
||||
},
|
||||
"options": {
|
||||
"ssl": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
options: {
|
||||
ssl: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
#### 3. Install the **Strapi Provider Upload AWS S3 Plugin**:
|
||||
@ -391,7 +391,7 @@ module.exports = {
|
||||
apps: [
|
||||
{
|
||||
name: 'your-app-name',
|
||||
cwd: '/home/ubuntu/my-strapi-project/my-project',
|
||||
cwd: '/home/ubuntu/my-project',
|
||||
script: 'npm',
|
||||
args: 'start',
|
||||
env: {
|
||||
@ -407,6 +407,18 @@ module.exports = {
|
||||
};
|
||||
```
|
||||
|
||||
You can also set your environment variables in a `.env` file in your project like so:
|
||||
|
||||
```
|
||||
DATABASE_HOST=your-unique-url.rds.amazonaws.com
|
||||
DATABASE_PORT=5432
|
||||
DATABASE_NAME=strapi
|
||||
DATABASE_USERNAME=postgres
|
||||
DATABASE_PASSWORD=Password
|
||||
```
|
||||
|
||||
We recommend you continue setting the `NODE_ENV` variable in the `ecosystem.config.js` file.
|
||||
|
||||
Use the following command to start `pm2`:
|
||||
|
||||
```bash
|
||||
|
||||
@ -277,44 +277,34 @@ Now you should be able to access your Strapi application on the public IP of you
|
||||
|
||||
#### 2. Modifying configurations to be more secure
|
||||
|
||||
By default Strapi will write the previous database settings in plain text to the `/srv/strapi/mystrapiapp/config/environments/development/database.json` file, and if you plan on pushing your project into Git you will not want these to be present. Thankfully Strapi can parse environment variables in JSON files.
|
||||
By default Strapi will predefine environment variables to use with your database config.
|
||||
|
||||
If we edit the above file using `nano` we can replace a few key settings:
|
||||
If we edit the `./config/database.js` file using `nano` we can replace a few key settings:
|
||||
|
||||
```bash
|
||||
nano /srv/strapi/mystrapiapp/config/environments/development/database.json
|
||||
nano /srv/strapi/mystrapiapp/config/database.js
|
||||
```
|
||||
|
||||
Using the following example we will remove any private information:
|
||||
|
||||
```json
|
||||
{
|
||||
"defaultConnection": "default",
|
||||
"connections": {
|
||||
"default": {
|
||||
"connector": "bookshelf",
|
||||
"settings": {
|
||||
"client": "mysql",
|
||||
"database": "${process.env.DB_NAME}",
|
||||
"host": "${process.env.DB_HOST}",
|
||||
"port": "${process.env.DB_PORT}",
|
||||
"username": "${process.env.DB_USER}",
|
||||
"password": "${process.env.DB_PASS}"
|
||||
```js
|
||||
module.exports = ({ env }) => ({
|
||||
defaultConnection: 'default',
|
||||
connections: {
|
||||
default: {
|
||||
connector: 'bookshelf',
|
||||
settings: {
|
||||
client: 'mysql',
|
||||
database: env('DB_NAME'),
|
||||
host: env('DB_HOST'),
|
||||
port: env('DB_PORT'),
|
||||
username: env('DB_USER'),
|
||||
password: env('DB_PASS'),
|
||||
},
|
||||
"options": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This now allows us to set the private database information using environment variables. Likewise we will want to do the same for the JWT (JSON Web Token) secret key located in `/srv/strapi/mystrapiapp/extensions/users-permissions/config/jwt.json`
|
||||
|
||||
Again using nano we will replace the secret key (do remember to take note of the generated one as we will need it later).
|
||||
|
||||
```json
|
||||
{
|
||||
"jwtSecret": "${process.env.JWT_SECRET}"
|
||||
}
|
||||
options: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
#### 3. Installing PM2 and running Strapi as a service
|
||||
@ -369,7 +359,7 @@ module.exports = {
|
||||
name: 'strapi-dev',
|
||||
cwd: '/srv/strapi/mystrapiapp',
|
||||
script: 'npm',
|
||||
args: 'run develop',
|
||||
args: 'start',
|
||||
env: {
|
||||
NODE_ENV: 'development',
|
||||
DB_HOST: 'localhost',
|
||||
@ -377,13 +367,26 @@ module.exports = {
|
||||
DB_NAME: 'strapi_dev',
|
||||
DB_USER: 'strapi',
|
||||
DB_PASS: 'mysecurepassword',
|
||||
JWT_SECRET: '54265f24-b1e3-472a-a005-f681a905488f',
|
||||
JWT_SECRET: 'aSecretKey',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
You can also set your environment variables in a `.env` file in your project like so:
|
||||
|
||||
```
|
||||
DB_HOST=localhost
|
||||
DB_PORT=5432
|
||||
DB_NAME=strapi_dev
|
||||
DB_USER=strapi
|
||||
DB_PASS=mysecurepassword
|
||||
JWT_SECRET=aSecretKey
|
||||
```
|
||||
|
||||
We recommend you continue setting the `NODE_ENV` variable in the `ecosystem.config.js` file.
|
||||
|
||||
Then use the following command to start the Strapi service:
|
||||
|
||||
```bash
|
||||
|
||||
@ -163,30 +163,30 @@ You will need the **database name**, **username** and **password** for later use
|
||||
- You must have [Git installed and set-up locally](https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup).
|
||||
- You must have created a repository for your Strapi project and have your development project initialized to this repository.
|
||||
|
||||
In your code editor, you will need to edit a file called `database.json`. Replace the contents of the file with the following.
|
||||
In your code editor, you will need to edit a file called `database.js`. Replace the contents of the file with the following.
|
||||
|
||||
`Path: ./config/environments/production`
|
||||
`Path: ./config/database.js`
|
||||
|
||||
```json
|
||||
{
|
||||
"defaultConnection": "default",
|
||||
"connections": {
|
||||
"default": {
|
||||
"connector": "bookshelf",
|
||||
"settings": {
|
||||
"client": "postgres",
|
||||
"host": "${process.env.DATABASE_HOST || '127.0.0.1'}",
|
||||
"port": "${process.env.DATABASE_PORT || 27017}",
|
||||
"database": "${process.env.DATABASE_NAME || 'strapi'}",
|
||||
"username": "${process.env.DATABASE_USERNAME || ''}",
|
||||
"password": "${process.env.DATABASE_PASSWORD || ''}"
|
||||
```js
|
||||
module.exports = ({ env }) => ({
|
||||
defaultConnection: 'default',
|
||||
connections: {
|
||||
default: {
|
||||
connector: 'bookshelf',
|
||||
settings: {
|
||||
client: 'postgres',
|
||||
host: env('DATABASE_HOST', '127.0.0.1'),
|
||||
port: env.int('DATABASE_PORT', 27017),
|
||||
database: env('DATABASE_NAME', 'strapi'),
|
||||
username: env('DATABASE_USERNAME', ''),
|
||||
password: env('DATABASE_PASSWORD', ''),
|
||||
},
|
||||
"options": {
|
||||
"ssl": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
options: {
|
||||
ssl: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
You are now ready to push these changes to Github:
|
||||
@ -284,6 +284,18 @@ module.exports = {
|
||||
};
|
||||
```
|
||||
|
||||
You can also set your environment variables in a `.env` file in your project like so:
|
||||
|
||||
```
|
||||
DATABASE_HOST=your-unique-url.rds.amazonaws.com
|
||||
DATABASE_PORT=5432
|
||||
DATABASE_NAME=strapi
|
||||
DATABASE_USERNAME=postgres
|
||||
DATABASE_PASSWORD=Password
|
||||
```
|
||||
|
||||
We recommend you continue setting the `NODE_ENV` variable in the `ecosystem.config.js` file.
|
||||
|
||||
Use the following command to start `pm2`:
|
||||
|
||||
```bash
|
||||
|
||||
@ -111,7 +111,7 @@ runtime: nodejs10
|
||||
instance_class: F2
|
||||
|
||||
env_variables:
|
||||
HOST: '<project_id>.appspot.com'
|
||||
HOST: '0.0.0.0'
|
||||
NODE_ENV: 'production'
|
||||
DATABASE_NAME: 'strapi'
|
||||
DATABASE_USERNAME: 'postgres'
|
||||
@ -132,7 +132,7 @@ runtime: nodejs10
|
||||
env: flex
|
||||
|
||||
env_variables:
|
||||
HOST: '<project_id>.appspot.com'
|
||||
HOST: '0.0.0.0'
|
||||
NODE_ENV: 'production'
|
||||
DATABASE_NAME: 'strapi'
|
||||
DATABASE_USERNAME: 'postgres'
|
||||
@ -172,52 +172,27 @@ yarn add pg
|
||||
|
||||
[Google App Engine requires](https://cloud.google.com/sql/docs/postgres/connect-app-engine) to connect to the database using the unix socket path, not an IP and port.
|
||||
|
||||
Edit `database.json`, and use the socket path as `host`.
|
||||
Edit `database.js`, and use the socket path as `host`.
|
||||
|
||||
```
|
||||
config/environments/production/database.json
|
||||
```
|
||||
`Path: ./config/env/production/database.js`.
|
||||
|
||||
```json
|
||||
{
|
||||
"defaultConnection": "default",
|
||||
"connections": {
|
||||
"default": {
|
||||
"connector": "bookshelf",
|
||||
"settings": {
|
||||
"client": "postgres",
|
||||
"host": "/cloudsql/${process.env.INSTANCE_CONNECTION_NAME}",
|
||||
"database": "${process.env.DATABASE_NAME}",
|
||||
"username": "${process.env.DATABASE_USERNAME}",
|
||||
"password": "${process.env.DATABASE_PASSWORD}"
|
||||
```js
|
||||
module.exports = ({ env }) => ({
|
||||
defaultConnection: 'default',
|
||||
connections: {
|
||||
default: {
|
||||
connector: 'bookshelf',
|
||||
settings: {
|
||||
client: 'postgres',
|
||||
host: `/cloudsql/${env('INSTANCE_CONNECTION_NAME')}`,
|
||||
database: env('DATABASE_NAME'),
|
||||
username: env('DATABASE_USERNAME'),
|
||||
password: env('DATABASE_PASSWORD'),
|
||||
},
|
||||
"options": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Edit `server.json` to pick up the deployed hostname from the `HOST` variable in `app.yaml`.
|
||||
|
||||
```
|
||||
config/environments/production/server.json
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"host": "${process.env.HOST}",
|
||||
"port": "${process.env.PORT || 1337}",
|
||||
"production": true,
|
||||
"proxy": {
|
||||
"enabled": false
|
||||
options: {},
|
||||
},
|
||||
},
|
||||
"cron": {
|
||||
"enabled": false
|
||||
},
|
||||
"admin": {
|
||||
"autoOpen": false
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### Auto-build after deploy
|
||||
@ -288,20 +263,18 @@ Click `Save`, and it's ready to go!
|
||||
|
||||
CORS is enabled by default, allowing `*` origin. You may want to limit the allowed origins.
|
||||
|
||||
```
|
||||
config/environments/production/security.json
|
||||
```
|
||||
Read the documentation [here](../concepts/middlewares.md)
|
||||
|
||||
**Changing the admin url**
|
||||
|
||||
```
|
||||
config/environments/production/server.json
|
||||
config/env/production/server.js
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"admin": {
|
||||
"path": "/dashboard"
|
||||
}
|
||||
}
|
||||
```js
|
||||
module.exports = {
|
||||
admin: {
|
||||
path: '/dashboard',
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
@ -196,29 +196,30 @@ Please replace these above values with your actual values.
|
||||
|
||||
#### 4. Update your database config file
|
||||
|
||||
Replace the contents of `database.json` with the following:
|
||||
Replace the contents of `database.js` with the following:
|
||||
|
||||
`Path: ./config/environments/production/database.json`.
|
||||
`Path: ./config/database.js`.
|
||||
|
||||
```json
|
||||
{
|
||||
"defaultConnection": "default",
|
||||
"connections": {
|
||||
"default": {
|
||||
"connector": "bookshelf",
|
||||
"settings": {
|
||||
"client": "postgres",
|
||||
"host": "${process.env.DATABASE_HOST}",
|
||||
"port": "${process.env.DATABASE_PORT}",
|
||||
"database": "${process.env.DATABASE_NAME}",
|
||||
"username": "${process.env.DATABASE_USERNAME}",
|
||||
"password": "${process.env.DATABASE_PASSWORD}",
|
||||
"ssl": true
|
||||
```js
|
||||
module.exports = ({ env }) => ({
|
||||
defaultConnection: 'default',
|
||||
connections: {
|
||||
default: {
|
||||
connector: 'bookshelf',
|
||||
settings: {
|
||||
client: 'postgres',
|
||||
host: env('DATABASE_HOST', '127.0.0.1'),
|
||||
port: env.int('DATABASE_PORT', 27017),
|
||||
database: env('DATABASE_NAME', 'strapi'),
|
||||
username: env('DATABASE_USERNAME', ''),
|
||||
password: env('DATABASE_PASSWORD', ''),
|
||||
},
|
||||
"options": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
options: {
|
||||
ssl: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
#### 5. Install the `pg` node module
|
||||
@ -263,26 +264,84 @@ Please replace the `<password>` and `my-database-name` values with the your actu
|
||||
|
||||
#### 2. Update your database config file
|
||||
|
||||
Replace the contents of `database.json` with the following:
|
||||
`Path: ./config/database.js`.
|
||||
|
||||
`Path: ./config/environments/production/database.json`.
|
||||
|
||||
```json
|
||||
{
|
||||
"defaultConnection": "default",
|
||||
"connections": {
|
||||
"default": {
|
||||
"connector": "mongoose",
|
||||
"settings": {
|
||||
"uri": "${process.env.DATABASE_URI}",
|
||||
"database": "${process.env.DATABASE_NAME}"
|
||||
```js
|
||||
module.exports = ({ env }) => ({
|
||||
defaultConnection: 'default',
|
||||
connections: {
|
||||
default: {
|
||||
connector: 'mongoose',
|
||||
settings: {
|
||||
uri: env('DATABASE_URI'),
|
||||
},
|
||||
"options": {
|
||||
"ssl": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
options: {
|
||||
ssl: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
If you need to configure the connection differently (e.g using `host`,`port`...) you should set the default database config like so:
|
||||
|
||||
`Path: ./config/database.js`.
|
||||
|
||||
```js
|
||||
module.exports = ({ env }) => ({
|
||||
defaultConnection: 'default',
|
||||
connections: {
|
||||
default: {
|
||||
connector: 'mongoose',
|
||||
settings: {},
|
||||
options: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Then set the development and the production configurations separatly:
|
||||
|
||||
`Path: ./config/env/development/database.js`.
|
||||
|
||||
```js
|
||||
module.exports = ({ env }) => ({
|
||||
defaultConnection: 'default',
|
||||
connections: {
|
||||
default: {
|
||||
connector: 'mongoose',
|
||||
settings: {
|
||||
host: env('DATABASE_HOST'),
|
||||
port: env.int('DATABASE_PORT'),
|
||||
database: env('DATABASE_NAME'),
|
||||
username: env('DATABASE_USERNAME'),
|
||||
password: env('DATABASE_PASSWORD'),
|
||||
},
|
||||
options: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
and finally for the `production` env:
|
||||
|
||||
`Path: ./config/env/production/database.js`.
|
||||
|
||||
```js
|
||||
module.exports = ({ env }) => ({
|
||||
defaultConnection: 'default',
|
||||
connections: {
|
||||
default: {
|
||||
connector: 'mongoose',
|
||||
settings: {
|
||||
uri: env('DATABASE_URI'),
|
||||
},
|
||||
options: {
|
||||
ssl: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
@ -90,30 +90,29 @@ Additional guides for optional software additions that compliment or improve the
|
||||
|
||||
### 1. Configure
|
||||
|
||||
Update the `production` settings with the IP or domain name where the project will be running.
|
||||
We always recommend you use environment variables to configure your application based on the environment. Here is an example:
|
||||
|
||||
**Path —** `./config/environments/production/server.json`.
|
||||
**Path —** `./config/server.js`.
|
||||
|
||||
```js
|
||||
{
|
||||
"host": "0.0.0.0", // IP, localhost, or 0.0.0.0
|
||||
"port": 1337
|
||||
}
|
||||
module.exports = ({ env }) => ({
|
||||
host: env('APP_HOST', '0.0.0.0'),
|
||||
port: env.int('NODE_PORT', 1337),
|
||||
});
|
||||
```
|
||||
|
||||
In case your database is not running on the same server, make sure that the environment of your production
|
||||
database (`./config/environments/production/database.json`) is set properly.
|
||||
Then you can create a `.env` file or directly use the deployment platform you use to set environment variables:
|
||||
|
||||
If you are passing a number of configuration item values via environment variables, which is always encouraged for production environment, read the section for [Dynamic Configuration](../concepts/configurations.md#dynamic-configurations). Here is an example:
|
||||
**Path —** `.env`.
|
||||
|
||||
**Path —** `./config/environments/production/server.json`.
|
||||
|
||||
```js
|
||||
{
|
||||
"host": "${process.env.APP_HOST || '0.0.0.0'}",
|
||||
"port": "${process.env.NODE_PORT || 1337}"
|
||||
}
|
||||
```
|
||||
APP_HOST=10.0.0.1
|
||||
NODE_PORT=1338
|
||||
```
|
||||
|
||||
::: tip
|
||||
To learn more about configuration you can read the documentation [here](../concepts/configurations.md)
|
||||
:::
|
||||
|
||||
### 2. Launch the server
|
||||
|
||||
|
||||
@ -633,7 +633,7 @@ If you would like to see the route of any specific **Content Type**, you need to
|
||||
|
||||
- Learn how to use Strapi with React ([Gatsby](https://blog.strapi.io/building-a-static-website-using-gatsby-and-strapi) or [Next.js](https://blog.strapi.io/strapi-next-setup/)) or Vue.js ([Nuxt.js](https://blog.strapi.io/cooking-a-deliveroo-clone-with-nuxt-vue-js-graphql-strapi-and-stripe-setup-part-1-7/)).
|
||||
- Read the **concepts** to deep dive into Strapi.
|
||||
- Get help on [StackOverflow](https://stackoverflow.com/questions/tagged/strapi).
|
||||
- Get help on [Github Discussions](https://github.com/strapi/strapi/discussions).
|
||||
- Read the [source code](https://github.com/strapi/strapi), [contribute](https://github.com/strapi/strapi/blob/master/CONTRIBUTING.md) or [give a star](https://github.com/strapi/strapi) on GitHub.
|
||||
- Follow us on [Twitter](https://twitter.com/strapijs) to get the latest news.
|
||||
- [Join the vibrant and active Strapi community](https://slack.strapi.io) on Slack.
|
||||
|
||||
@ -120,7 +120,7 @@ Here we are! The list of **restaurants** is accessible at [`http://localhost:133
|
||||
|
||||
- Learn how to use Strapi with React ([Gatsby](https://blog.strapi.io/building-a-static-website-using-gatsby-and-strapi) or [Next.js](https://blog.strapi.io/strapi-next-setup/)) or Vue.js ([Nuxt.js](https://blog.strapi.io/cooking-a-deliveroo-clone-with-nuxt-vue-js-graphql-strapi-and-stripe-setup-part-1-7/)).
|
||||
- Read the **concepts** and do the [Tutorial](quick-start-tutorial.md) to deep dive into Strapi.
|
||||
- Get help on [StackOverflow](https://stackoverflow.com/questions/tagged/strapi).
|
||||
- Get help on [Github Discussions](https://github.com/strapi/strapi/discussions).
|
||||
- Read the [source code](https://github.com/strapi/strapi), [contribute](https://github.com/strapi/strapi/blob/master/CONTRIBUTING.md) or [give a star](https://github.com/strapi/strapi) on GitHub.
|
||||
- Follow us on [Twitter](https://twitter.com/strapijs) to get the latest news.
|
||||
- [Join the vibrant and active Strapi community](https://slack.strapi.io) on Slack.
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# 💬 Troubleshooting
|
||||
|
||||
Below are solutions to some common issues that you may experience when working with Strapi. You can also post questions to [StackOverflow](https://stackoverflow.com/questions/tagged/strapi) or reach out to the members of our [Slack](https://slack.strapi.io) community!
|
||||
Below are solutions to some common issues that you may experience when working with Strapi. You can also post questions to [Github Discussions](https://github.com/strapi/strapi/discussions) or reach out to the members of our [Slack](https://slack.strapi.io) community!
|
||||
|
||||
[[toc]]
|
||||
|
||||
@ -10,7 +10,7 @@ Strapi is offered as free and open-source for users who wish to self-host the so
|
||||
|
||||
### Community Support
|
||||
|
||||
[StackOverflow](https://stackoverflow.com/search?q=strapi) is great first place to reach out for help. Our community and Core developers often check this platform and answer posts tagged with `strapi`.
|
||||
[Github Discussions](https://github.com/strapi/strapi/discussions) is great first place to reach out for help. Our community and Core developers often check this platform and answer posts.
|
||||
|
||||
Another option to get help is our [Community Slack](https://slack.strapi.io). Please keep all questions on the `#help` channel, be considerate, and remember that _you are getting free help for a free product_.
|
||||
|
||||
|
||||
@ -42,17 +42,18 @@ module.exports = strapi => {
|
||||
};
|
||||
```
|
||||
|
||||
When the hook is created, we have to enable it to say to Strapi to use this hook.
|
||||
When the hook is created, we have set it to `enabled` in order for Strapi to laod it. You will need to create or edit the file `./config/hook.js`.
|
||||
|
||||
**Path —** `./config/hook.json`
|
||||
**Path —** `./config/hook.js`
|
||||
|
||||
```json
|
||||
{
|
||||
...
|
||||
"github": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
```js
|
||||
module.exports = {
|
||||
settings: {
|
||||
github: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
Now you can start your application, you should see a log `my hook is loaded` in your terminal.
|
||||
@ -62,16 +63,23 @@ Now you can start your application, you should see a log `my hook is loaded` in
|
||||
First lets update the config file to add your [GitHub token](https://github.com/settings/tokens).
|
||||
By following the [documentation](https://octokit.github.io/rest.js/#authentication) you will also find the way to use GitHub applications.
|
||||
|
||||
**Path —** `./config/hook.json`
|
||||
**Path —** `./config/hook.js`
|
||||
|
||||
```json
|
||||
{
|
||||
...
|
||||
"github": {
|
||||
"enabled": true,
|
||||
"token": "bf78d4fc3c1767019870476d6d7cc8961383d80f"
|
||||
}
|
||||
}
|
||||
```js
|
||||
module.exports = {
|
||||
settings: {
|
||||
github: {
|
||||
enabled: true,
|
||||
token: process.env.GITHUB_TOKEN,
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
**Path -** `.env`
|
||||
|
||||
```
|
||||
GITHUB_TOKEN=bf78d4fc3c1767019870476d6d7cc8961383d80f
|
||||
```
|
||||
|
||||
Now we have to load the GitHub client.
|
||||
@ -84,10 +92,10 @@ const GitHubAPI = require('@octokit/rest');
|
||||
module.exports = strapi => {
|
||||
return {
|
||||
async initialize() {
|
||||
const { token } = strapi.config.hook.github;
|
||||
const { token } = strapi.config.get('hook.settings.github');
|
||||
|
||||
strapi.services.github = new GitHubAPI({
|
||||
userAgent: `${strapi.config.info.name} v${strapi.config.info.version}`,
|
||||
userAgent: `${strapi.config.get('info.name')} v${strapi.config.get('info.version')}`,
|
||||
auth: `token ${token}`,
|
||||
});
|
||||
},
|
||||
@ -111,43 +119,3 @@ module.exports = async () => {
|
||||
```
|
||||
|
||||
Restart your server and you should see your GitHub profile data.
|
||||
|
||||
## Configs by environment
|
||||
|
||||
You would probably want specific configurations for development and production environment.
|
||||
|
||||
To do so, we will update some configurations.
|
||||
|
||||
You have to move your `github` configs from `./config/hook.json` to `./config/environments/development.json`, then remove it from the `hook.json` file.
|
||||
|
||||
And in your GitHub hook, you will have to replace `strapi.config.hook.github` by `strapi.config.currentEnvironment.github` to access to the configs.
|
||||
|
||||
**Path —** `./config/environments/development.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"github": {
|
||||
"enabled": true,
|
||||
"token": "806506ab855a94e8608148315eeb39a44c29aee1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Path —** `./hooks/github/index.js`
|
||||
|
||||
```js
|
||||
const GitHubAPI = require('@octokit/rest');
|
||||
|
||||
module.exports = strapi => {
|
||||
return {
|
||||
async initialize() {
|
||||
const { token } = strapi.config.currentEnvironment.github;
|
||||
|
||||
strapi.services.github = new GitHubAPI({
|
||||
userAgent: `${strapi.config.info.name} v${strapi.config.info.version}`,
|
||||
auth: `token ${token}`,
|
||||
});
|
||||
},
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
@ -4,7 +4,7 @@ Strapi gives you the option to choose the most appropriate database for your pro
|
||||
**MariaDB**. The following documentation covers how to install these databases locally (for development purposes) and on various hosted or cloud server solutions (for staging or production purposes).
|
||||
|
||||
::: tip
|
||||
Deploying **Strapi** itself is covered in the [Deployment Guide](deployment.md).
|
||||
Deploying **Strapi** itself is covered in the [Deployment Guide](../getting-started/deployment.md).
|
||||
:::
|
||||
|
||||
## SQLite Installation
|
||||
@ -309,27 +309,33 @@ MongoDB Atlas automatically exposes the database credentials into a single envir
|
||||
Please note the `<password>` after your `username`. In this example, after `mongodb://paulbocuse:`. You will need to replace the `<password>` with the password you created earlier for this user in your **MongoDB Atlas** account.
|
||||
:::
|
||||
|
||||
#### 5. Update and replace your existing `/database.json` config file for the appropriate environment (development | production).
|
||||
#### 5. Update and replace your existing `/database.js` config file for the appropriate environment (development | production).
|
||||
|
||||
Replace the contents of `/database.json` with the following and replace **< password >** with the password of the user of your database you created earlier:
|
||||
|
||||
`Path: ./config/environments/(development|production)/database.json`.
|
||||
`Path: ./config/database.js`.
|
||||
|
||||
```json
|
||||
{
|
||||
"defaultConnection": "default",
|
||||
"connections": {
|
||||
"default": {
|
||||
"connector": "mongoose",
|
||||
"settings": {
|
||||
"uri": "mongodb://paulbocuse:<password>@strapidatabase-shard-00-00-fxxx6c.mongodb.net:27017,strapidatabase-shard-00-01-fxxxc.mongodb.net:27017,strapidatabase-shard-00-02-fxxxc.mongodb.net:27017/test?ssl=true&replicaSet=strapidatabase-shard-0&authSource=admin&retryWrites=true&w=majority"
|
||||
```js
|
||||
module.exports = ({ env }) => ({
|
||||
defaultConnection: 'default',
|
||||
connections: {
|
||||
default: {
|
||||
connector: 'mongoose',
|
||||
settings: {
|
||||
uri: env('DATABASE_URI'),
|
||||
},
|
||||
"options": {
|
||||
"ssl": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
options: {
|
||||
ssl: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
`Path: .env`
|
||||
|
||||
```
|
||||
DATABASE_URI=mongodb://paulbocuse:<password>@strapidatabase-shard-00-00-fxxx6c.mongodb.net:27017,strapidatabase-shard-00-01-fxxxc.mongodb.net:27017,strapidatabase-shard-00-02-fxxxc.mongodb.net:27017/test?ssl=true&replicaSet=strapidatabase-shard-0&authSource=admin&retryWrites=true&w=majority
|
||||
```
|
||||
|
||||
::: warning NOTE
|
||||
@ -340,7 +346,7 @@ The above configuration will create a database called `strapi`, the _default dat
|
||||
:::
|
||||
|
||||
::: danger WARNING
|
||||
We recommend replacing sensitive (eg. "URI string" above) information in your database.json files before uploading your project to a public repository such as GitHub. For more information about using environment variables, please read [dynamic configurations](../concepts/configurations.md#dynamic-configurations).
|
||||
We recommend replacing sensitive (eg. "URI string" above) information in your database configuration files before uploading your project to a public repository such as GitHub. For more information about using environment variables, please read [configurations](../concepts/configurations.md).
|
||||
|
||||
:::
|
||||
|
||||
|
||||
@ -67,28 +67,26 @@ It's important to call `throw(error);` to avoid stopping the middleware stack. I
|
||||
|
||||
Make sure your middleware is added at the end of the middleware stack.
|
||||
|
||||
**Path —** `./config/middleware.json`
|
||||
**Path —** `./config/middleware.js`
|
||||
|
||||
```json
|
||||
{
|
||||
...
|
||||
"after": [
|
||||
"parser",
|
||||
"router",
|
||||
"sentry"
|
||||
]
|
||||
}
|
||||
}
|
||||
```js
|
||||
module.exports = {
|
||||
load: {
|
||||
after: ['parser', 'router', 'sentry'],
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
And finally you have to enable the middleware.
|
||||
|
||||
**Path —** `./config/environments/**/middleware.json`
|
||||
**Path —** `./config/middleware.js`
|
||||
|
||||
```json
|
||||
{
|
||||
"sentry": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
```js
|
||||
module.exports = {
|
||||
settings: {
|
||||
sentry: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
@ -222,7 +222,6 @@ Wysiwyg.propTypes = {
|
||||
};
|
||||
|
||||
export default Wysiwyg;
|
||||
|
||||
```
|
||||
|
||||
#### Implementing CKEditor
|
||||
|
||||
@ -38,7 +38,7 @@ module.exports = {
|
||||
};
|
||||
```
|
||||
|
||||
Make sure the enabled cron config is set to true in `./config/environments/**/server.json` file.
|
||||
Make sure the enabled cron config is set to true in `./config/server.js` file.
|
||||
|
||||
::: tip
|
||||
Please note that Strapi's built in CRON feature will not work if you plan to use `pm2` or node based clustering. You will need to execute these CRON tasks outside of Strapi.
|
||||
@ -58,20 +58,15 @@ module.exports = {
|
||||
// fetch articles to publish
|
||||
const draftArticleToPublish = await strapi.api.article.services.article.find({
|
||||
status: 'draft',
|
||||
publish_at_lt: new Date()
|
||||
publish_at_lt: new Date(),
|
||||
});
|
||||
|
||||
// update status of articles
|
||||
draftArticleToPublish.forEach(async (article) => {
|
||||
await strapi.api.article.services.article.update(
|
||||
{id: article.id},
|
||||
{status: 'published'}
|
||||
);
|
||||
draftArticleToPublish.forEach(async article => {
|
||||
await strapi.api.article.services.article.update({ id: article.id }, { status: 'published' });
|
||||
});
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
And tada!
|
||||
|
||||
|
||||
|
||||
@ -27,7 +27,7 @@ To create a project head over to the Strapi [listing on the marketplace](https:/
|
||||
|
||||
### Step 3: Visit your app
|
||||
|
||||
Please note that it may take anywhere from 30 seconds to a few minutes for the droplet to startup, when it does you should see it in your [droplets list](https://cloud.digitalocean.com/droplets).
|
||||
Please note that it may take anywhere from 30 seconds to a few minutes for the droplet to startup, when it does you should see it in your [droplets list](https://cloud.digitalocean.com/droplets).
|
||||
|
||||
::: warning
|
||||
After the droplet has started, it will take a few more minutes to finish the Strapi installation.
|
||||
@ -151,19 +151,10 @@ pm2 stop strapi-develop
|
||||
psql -c "ALTER USER strapi with password 'your-new-password';"
|
||||
```
|
||||
|
||||
- Update the `/srv/strapi/strapi/config/environments/development/database.json` file with the new password.
|
||||
- Update the `/srv/strapi/strapi/config/.env` file with the new password.
|
||||
|
||||
```json
|
||||
...
|
||||
"settings": {
|
||||
"client": "postgres",
|
||||
"host": "127.0.0.1",
|
||||
"port": "5432",
|
||||
"database": "strapi",
|
||||
"username": "strapi",
|
||||
"password": "your-new-password"
|
||||
},
|
||||
...
|
||||
```
|
||||
DATABASE_PASSWORD=your-new-password
|
||||
```
|
||||
|
||||
- Restart Strapi and confirm the password change was successful
|
||||
|
||||
@ -55,7 +55,7 @@ services:
|
||||
POSTGRES_USER: strapi
|
||||
POSTGRES_PASSWORD: strapi
|
||||
volumes:
|
||||
- ./data:/data/postgres
|
||||
- ./data:/var/lib/postgresql/data
|
||||
ports:
|
||||
- '5432:5432'
|
||||
```
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
Upgrading your Strapi application to `v3.0.0-beta.18`.
|
||||
|
||||
**Make sure your server is not running until then end of the migration**
|
||||
**Make sure your server is not running until the end of the migration**
|
||||
|
||||
## Upgrading your dependencies
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
Upgrading your Strapi application to `v3.0.0-beta.19`.
|
||||
|
||||
**Make sure your server is not running until then end of the migration**
|
||||
**Make sure your server is not running until the end of the migration**
|
||||
|
||||
## Upgrading your dependencies
|
||||
|
||||
|
||||
@ -60,19 +60,23 @@ Each plugin exports all its configurations in an object. This object is located
|
||||
|
||||
Here are its properties:
|
||||
|
||||
| key | type | value |
|
||||
| ------------------------- | -------- | :-------------------------------------------------------------------------------- |
|
||||
| blockerComponent | node | can be either `null` or React node (e.g. `() => <div />`) |
|
||||
| blockerComponentProps | object | `{}` |
|
||||
| description | string | `My awesome plugin` |
|
||||
| id | string | Id of the plugin from the `package.json` |
|
||||
| initializer | node | Refer to the [Initializer documentation](#initializer) |
|
||||
| injectedComponents | array | Refer to the [Injected Component documentation](#injected-components) |
|
||||
| leftMenuLinks | array | `[]` |
|
||||
| lifecycles | function | Refer to the [Lifecycle documentation](#lifecycle) |
|
||||
| mainComponent | node | The plugin's App container |
|
||||
| preventComponentRendering | boolean | Wheter or not display the plugin's blockerComponent instead of the main component |
|
||||
| trads | object | The plugin's translation files |
|
||||
| key | type | Description |
|
||||
| ------------------------- | ------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| blockerComponent | node | Props can be either `null` or React node (e.g. `() => <div />`) |
|
||||
| blockerComponentProps | object | Props to provide to customise the [blockerComponent](https://github.com/strapi/strapi/blob/58588e10e5d15921b0966e20ce1bc6cde70df5cc/packages/strapi-helper-plugin/lib/src/components/BlockerComponent/index.js#L81-L86) |
|
||||
| description | string | Plugin's description retrieved from the package.json |
|
||||
| id | string | Id of the plugin from the `package.json` |
|
||||
| initializer | node | Refer to the [Initializer documentation](#initializer) |
|
||||
| injectedComponents | array | Refer to the [Injected Component documentation](#injected-components) |
|
||||
| isReady | boolean | The app will load until this proprety is true |
|
||||
| leftMenuLinks | array | Array of links to inject in the menu |
|
||||
| mainComponent | node | The plugin's App container, setting it to null will prevent the plugin from being displayed in the menu |
|
||||
| name | string | The plugin's name retrieved from the package.json |
|
||||
| pluginLogo | file | The plugin's logo |
|
||||
| preventComponentRendering | boolean | Whether or not display the plugin's blockerComponent instead of the main component |
|
||||
| settings | object | Refer to the [Plugins settings API](./frontend-settings-api.md) |
|
||||
| reducers | object | The plugin's redux reducers |
|
||||
| trads | object | The plugin's translation files |
|
||||
|
||||
### Initializer
|
||||
|
||||
@ -126,16 +130,8 @@ class Initializer extends React.PureComponent {
|
||||
}
|
||||
|
||||
// Prevent the plugin from being rendered if currentEnvironment === PRODUCTION
|
||||
this.props.updatePlugin(
|
||||
pluginId,
|
||||
'preventComponentRendering',
|
||||
preventComponentRendering
|
||||
);
|
||||
this.props.updatePlugin(
|
||||
pluginId,
|
||||
'blockerComponentProps',
|
||||
blockerComponentProps
|
||||
);
|
||||
this.props.updatePlugin(pluginId, 'preventComponentRendering', preventComponentRendering);
|
||||
this.props.updatePlugin(pluginId, 'blockerComponentProps', blockerComponentProps);
|
||||
// Emit the event plugin ready
|
||||
this.props.updatePlugin(pluginId, 'isReady', true);
|
||||
}
|
||||
@ -188,11 +184,7 @@ class App extends React.Component {
|
||||
return (
|
||||
<div>
|
||||
<Switch>
|
||||
<Route
|
||||
exact
|
||||
path={`/plugins/${pluginId}/user/:id`}
|
||||
component={UserPage}
|
||||
/>
|
||||
<Route exact path={`/plugins/${pluginId}/user/:id`} component={UserPage} />
|
||||
</Switch>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -101,7 +101,7 @@ Here are the file that needs to be created in order to change the documentation
|
||||
},
|
||||
"x-strapi-config": {
|
||||
"path": "/documentation",
|
||||
"showGeneratedFiles": true",
|
||||
"showGeneratedFiles": true,
|
||||
"pluginsForWhichToGenerateDoc": [
|
||||
"email",
|
||||
"upload",
|
||||
|
||||
@ -263,6 +263,10 @@ query {
|
||||
|
||||
To simplify and automate the build of the GraphQL schema, we introduced the Shadow CRUD feature. It automatically generates the type definition, queries, mutations and resolvers based on your models. The feature also lets you make complex query with many arguments such as `limit`, `sort`, `start` and `where`.
|
||||
|
||||
::: tip NOTE
|
||||
If you use a local plugin, the controller methods of your plugin are not created by default. In order for the Shadow CRUD to work you have to define them in your controllers for each of your models. You can find examples of controllers `findOne`, `find`, `create`, `update` and `delete` there : [Core controllers](../concepts/controllers.html#core-controllers).
|
||||
:::
|
||||
|
||||
### Example
|
||||
|
||||
If you've generated an API called `Restaurant` using the CLI `strapi generate:api restaurant` or the administration panel, your model looks like this:
|
||||
@ -517,7 +521,7 @@ module.exports = {
|
||||
`,
|
||||
mutation: `
|
||||
attachRestaurantToChef(id: ID, chefID: ID): Restaurant!
|
||||
`
|
||||
`,
|
||||
resolver: {
|
||||
Query: {
|
||||
restaurant: {
|
||||
|
||||
@ -328,9 +328,27 @@ To enable the provider, create or edit the file at `./extensions/upload/config/s
|
||||
|
||||
Make sure to read the provider's `README` to know what are the possible parameters.
|
||||
|
||||
::: tip
|
||||
Some providers may have additional settings such as the AWS S3 needs an API endpoint URL. You can find a list of these for AWS [here](https://docs.aws.amazon.com/general/latest/gr/ses.html)
|
||||
:::
|
||||
### Configuration per envrionment
|
||||
|
||||
When configuring your upload provider you might want to change the configuration based on the `NODE_ENV` environment variable or use environment specific credentials.
|
||||
|
||||
You can do so using a `settings.js` file:
|
||||
|
||||
```js
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
module.exports = {
|
||||
provider: 'providerName',
|
||||
providerOptions: {
|
||||
cloud_name: process.env.PROVIDER_CLOUD_NAME,
|
||||
api_key: process.env.PROVIDER_API_KEY,
|
||||
api_secret: process.env.PROVIDER_API_SECRET,
|
||||
},
|
||||
};
|
||||
} else {
|
||||
// to use the default local provider you can return an empty configuration
|
||||
module.exports = {};
|
||||
}
|
||||
```
|
||||
|
||||
## Create providers
|
||||
|
||||
|
||||
@ -70,7 +70,7 @@ axios
|
||||
})
|
||||
.catch(error => {
|
||||
// Handle error.
|
||||
console.log('An error occurred:', error);
|
||||
console.log('An error occurred:', error.response);
|
||||
});
|
||||
```
|
||||
|
||||
@ -99,7 +99,7 @@ axios
|
||||
})
|
||||
.catch(error => {
|
||||
// Handle error.
|
||||
console.log('An error occurred:', error);
|
||||
console.log('An error occurred:', error.response);
|
||||
});
|
||||
```
|
||||
|
||||
@ -128,7 +128,7 @@ axios
|
||||
})
|
||||
.catch(error => {
|
||||
// Handle error.
|
||||
console.log('An error occurred:', error);
|
||||
console.log('An error occurred:', error.response);
|
||||
});
|
||||
```
|
||||
|
||||
@ -257,7 +257,7 @@ Then fill the informations:
|
||||
|
||||
- **Enable**: `ON`
|
||||
- **Client ID**: 226437944084-o2mojv5i4lfnng9q8kq3jkf5v03avemk.apps.googleusercontent.com
|
||||
- **Client ID**: aiTbMoiuJQflSBy6uQrfgsni
|
||||
- **Client Secret**: aiTbMoiuJQflSBy6uQrfgsni
|
||||
- **The redirect URL to your front-end app**: `http://localhost:3000/connect/google`
|
||||
|
||||
:::
|
||||
@ -486,7 +486,7 @@ axios
|
||||
})
|
||||
.catch(error => {
|
||||
// Handle error.
|
||||
console.log('An error occurred:', error);
|
||||
console.log('An error occurred:', error.response);
|
||||
});
|
||||
```
|
||||
|
||||
@ -519,7 +519,7 @@ axios
|
||||
})
|
||||
.catch(error => {
|
||||
// Handle error.
|
||||
console.log('An error occurred:', error);
|
||||
console.log('An error occurred:', error.response);
|
||||
});
|
||||
```
|
||||
|
||||
@ -545,7 +545,7 @@ axios
|
||||
})
|
||||
.catch(error => {
|
||||
// Handle error.
|
||||
console.err('An error occured:', err);
|
||||
console.error('An error occured:', error.response);
|
||||
});
|
||||
```
|
||||
|
||||
@ -742,8 +742,18 @@ You can update these templates under **Plugins** > **Roles & Permissions** > **E
|
||||
|
||||
## Security configuration
|
||||
|
||||
JWT tokens can be verified and trusted because the information is digitally signed. To sign a token a _secret_ is required. By default Strapi generates one that is stored in `./your-app/extensions/users-permissions/config/jwt.json`. This is useful during development but for security reasons it is **recommended** to set a custom token via an environment variable `JWT_SECRET` when deploying to production. It is also possible to modify `jwt.json` file to accept `JWT_TOKEN` automatically by doing following ([docs](https://strapi.io/documentation/3.0.0-beta.x/concepts/configurations.html#dynamic-configurations)).
|
||||
JWT tokens can be verified and trusted because the information is digitally signed. To sign a token a _secret_ is required. By default Strapi generates one that is stored in `./extensions/users-permissions/config/jwt.js`. This is useful during development but for security reasons it is **recommended** to set a custom token via an environment variable `JWT_SECRET` when deploying to production.
|
||||
|
||||
By default you can set a `JWT_SECRET` environment variable and it will be used as secret. If you want to use another variable you can update the configuration file.
|
||||
|
||||
**Path -** `./extensions/users-permissions/config/jwt.js`.
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
jwtSecret: process.env.SOME_ENV_VAR,
|
||||
};
|
||||
```
|
||||
"jwtSecret": "${process.env.JWT_SECRET}"
|
||||
```
|
||||
|
||||
::: tip
|
||||
You can learn more on configuration in the documentation [here](../concepts/configurations.md)
|
||||
:::
|
||||
|
||||
2
examples/getstarted/.env.example
Normal file
2
examples/getstarted/.env.example
Normal file
@ -0,0 +1,2 @@
|
||||
HOST=localhost
|
||||
PORT=1337
|
||||
@ -4,41 +4,4 @@
|
||||
* Lifecycle callbacks for the `Address` model.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
// Before saving a value.
|
||||
// Fired before an `insert` or `update` query.
|
||||
// beforeSave: async (model, attrs, options) => {},
|
||||
// After saving a value.
|
||||
// Fired after an `insert` or `update` query.
|
||||
// afterSave: async (model, response, options) => {},
|
||||
// Before fetching a value.
|
||||
// Fired before a `fetch` operation.
|
||||
// beforeFetch: async (model, columns, options) => {},
|
||||
// After fetching a value.
|
||||
// Fired after a `fetch` operation.
|
||||
// afterFetch: async (model, response, options) => {},
|
||||
// Before fetching all values.
|
||||
// Fired before a `fetchAll` operation.
|
||||
// beforeFetchAll: async (model, columns, options) => {},
|
||||
// After fetching all values.
|
||||
// Fired after a `fetchAll` operation.
|
||||
// afterFetchAll: async (model, response, options) => {},
|
||||
// Before creating a value.
|
||||
// Fired before an `insert` query.
|
||||
// beforeCreate: async (model, attrs, options) => {},
|
||||
// After creating a value.
|
||||
// Fired after an `insert` query.
|
||||
// afterCreate: async (model, attrs, options) => {},
|
||||
// Before updating a value.
|
||||
// Fired before an `update` query.
|
||||
// beforeUpdate: async (model, attrs, options) => {},
|
||||
// After updating a value.
|
||||
// Fired after an `update` query.
|
||||
// afterUpdate: async (model, attrs, options) => {},
|
||||
// Before destroying a value.
|
||||
// Fired before a `delete` query.
|
||||
// beforeDestroy: async (model, attrs, options) => {},
|
||||
// After destroying a value.
|
||||
// Fired after a `delete` query.
|
||||
// afterDestroy: async (model, attrs, options) => {}
|
||||
};
|
||||
module.exports = {};
|
||||
|
||||
@ -4,41 +4,4 @@
|
||||
* Lifecycle callbacks for the `Category` model.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
// Before saving a value.
|
||||
// Fired before an `insert` or `update` query.
|
||||
// beforeSave: async (model, attrs, options) => {},
|
||||
// After saving a value.
|
||||
// Fired after an `insert` or `update` query.
|
||||
// afterSave: async (model, response, options) => {},
|
||||
// Before fetching a value.
|
||||
// Fired before a `fetch` operation.
|
||||
// beforeFetch: async (model, columns, options) => {},
|
||||
// After fetching a value.
|
||||
// Fired after a `fetch` operation.
|
||||
// afterFetch: async (model, response, options) => {},
|
||||
// Before fetching all values.
|
||||
// Fired before a `fetchAll` operation.
|
||||
// beforeFetchAll: async (model, columns, options) => {},
|
||||
// After fetching all values.
|
||||
// Fired after a `fetchAll` operation.
|
||||
// afterFetchAll: async (model, response, options) => {},
|
||||
// Before creating a value.
|
||||
// Fired before an `insert` query.
|
||||
// beforeCreate: async (model, attrs, options) => {},
|
||||
// After creating a value.
|
||||
// Fired after an `insert` query.
|
||||
// afterCreate: async (model, attrs, options) => {},
|
||||
// Before updating a value.
|
||||
// Fired before an `update` query.
|
||||
// beforeUpdate: async (model, attrs, options) => {},
|
||||
// After updating a value.
|
||||
// Fired after an `update` query.
|
||||
// afterUpdate: async (model, attrs, options) => {},
|
||||
// Before destroying a value.
|
||||
// Fired before a `delete` query.
|
||||
// beforeDestroy: async (model, attrs, options) => {},
|
||||
// After destroying a value.
|
||||
// Fired after a `delete` query.
|
||||
// afterDestroy: async (model, attrs, options) => {}
|
||||
};
|
||||
module.exports = {};
|
||||
|
||||
@ -4,41 +4,4 @@
|
||||
* Lifecycle callbacks for the `Country` model.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
// Before saving a value.
|
||||
// Fired before an `insert` or `update` query.
|
||||
// beforeSave: async (model, attrs, options) => {},
|
||||
// After saving a value.
|
||||
// Fired after an `insert` or `update` query.
|
||||
// afterSave: async (model, response, options) => {},
|
||||
// Before fetching a value.
|
||||
// Fired before a `fetch` operation.
|
||||
// beforeFetch: async (model, columns, options) => {},
|
||||
// After fetching a value.
|
||||
// Fired after a `fetch` operation.
|
||||
// afterFetch: async (model, response, options) => {},
|
||||
// Before fetching all values.
|
||||
// Fired before a `fetchAll` operation.
|
||||
// beforeFetchAll: async (model, columns, options) => {},
|
||||
// After fetching all values.
|
||||
// Fired after a `fetchAll` operation.
|
||||
// afterFetchAll: async (model, response, options) => {},
|
||||
// Before creating a value.
|
||||
// Fired before an `insert` query.
|
||||
// beforeCreate: async (model, attrs, options) => {},
|
||||
// After creating a value.
|
||||
// Fired after an `insert` query.
|
||||
// afterCreate: async (model, attrs, options) => {},
|
||||
// Before updating a value.
|
||||
// Fired before an `update` query.
|
||||
// beforeUpdate: async (model, attrs, options) => {},
|
||||
// After updating a value.
|
||||
// Fired after an `update` query.
|
||||
// afterUpdate: async (model, attrs, options) => {},
|
||||
// Before destroying a value.
|
||||
// Fired before a `delete` query.
|
||||
// beforeDestroy: async (model, attrs, options) => {},
|
||||
// After destroying a value.
|
||||
// Fired after a `delete` query.
|
||||
// afterDestroy: async (model, attrs, options) => {}
|
||||
};
|
||||
module.exports = {};
|
||||
|
||||
@ -4,41 +4,4 @@
|
||||
* Lifecycle callbacks for the `homepage` model.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
// Before saving a value.
|
||||
// Fired before an `insert` or `update` query.
|
||||
// beforeSave: async (model, attrs, options) => {},
|
||||
// After saving a value.
|
||||
// Fired after an `insert` or `update` query.
|
||||
// afterSave: async (model, response, options) => {},
|
||||
// Before fetching a value.
|
||||
// Fired before a `fetch` operation.
|
||||
// beforeFetch: async (model, columns, options) => {},
|
||||
// After fetching a value.
|
||||
// Fired after a `fetch` operation.
|
||||
// afterFetch: async (model, response, options) => {},
|
||||
// Before fetching all values.
|
||||
// Fired before a `fetchAll` operation.
|
||||
// beforeFetchAll: async (model, columns, options) => {},
|
||||
// After fetching all values.
|
||||
// Fired after a `fetchAll` operation.
|
||||
// afterFetchAll: async (model, response, options) => {},
|
||||
// Before creating a value.
|
||||
// Fired before an `insert` query.
|
||||
// beforeCreate: async (model, attrs, options) => {},
|
||||
// After creating a value.
|
||||
// Fired after an `insert` query.
|
||||
// afterCreate: async (model, attrs, options) => {},
|
||||
// Before updating a value.
|
||||
// Fired before an `update` query.
|
||||
// beforeUpdate: async (model, attrs, options) => {},
|
||||
// After updating a value.
|
||||
// Fired after an `update` query.
|
||||
// afterUpdate: async (model, attrs, options) => {},
|
||||
// Before destroying a value.
|
||||
// Fired before a `delete` query.
|
||||
// beforeDestroy: async (model, attrs, options) => {},
|
||||
// After destroying a value.
|
||||
// Fired after a `delete` query.
|
||||
// afterDestroy: async (model, attrs, options) => {}
|
||||
};
|
||||
module.exports = {};
|
||||
|
||||
@ -14,7 +14,8 @@
|
||||
},
|
||||
"slug": {
|
||||
"type": "uid",
|
||||
"targetField": "title"
|
||||
"targetField": "title",
|
||||
"required": true
|
||||
},
|
||||
"single": {
|
||||
"model": "file",
|
||||
|
||||
@ -4,41 +4,4 @@
|
||||
* Lifecycle callbacks for the `Like` model.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
// Before saving a value.
|
||||
// Fired before an `insert` or `update` query.
|
||||
// beforeSave: async (model, attrs, options) => {},
|
||||
// After saving a value.
|
||||
// Fired after an `insert` or `update` query.
|
||||
// afterSave: async (model, response, options) => {},
|
||||
// Before fetching a value.
|
||||
// Fired before a `fetch` operation.
|
||||
// beforeFetch: async (model, columns, options) => {},
|
||||
// After fetching a value.
|
||||
// Fired after a `fetch` operation.
|
||||
// afterFetch: async (model, response, options) => {},
|
||||
// Before fetching all values.
|
||||
// Fired before a `fetchAll` operation.
|
||||
// beforeFetchAll: async (model, columns, options) => {},
|
||||
// After fetching all values.
|
||||
// Fired after a `fetchAll` operation.
|
||||
// afterFetchAll: async (model, response, options) => {},
|
||||
// Before creating a value.
|
||||
// Fired before an `insert` query.
|
||||
// beforeCreate: async (model, attrs, options) => {},
|
||||
// After creating a value.
|
||||
// Fired after an `insert` query.
|
||||
// afterCreate: async (model, attrs, options) => {},
|
||||
// Before updating a value.
|
||||
// Fired before an `update` query.
|
||||
// beforeUpdate: async (model, attrs, options) => {},
|
||||
// After updating a value.
|
||||
// Fired after an `update` query.
|
||||
// afterUpdate: async (model, attrs, options) => {},
|
||||
// Before destroying a value.
|
||||
// Fired before a `delete` query.
|
||||
// beforeDestroy: async (model, attrs, options) => {},
|
||||
// After destroying a value.
|
||||
// Fired after a `delete` query.
|
||||
// afterDestroy: async (model, attrs, options) => {}
|
||||
};
|
||||
module.exports = {};
|
||||
|
||||
@ -4,41 +4,4 @@
|
||||
* Lifecycle callbacks for the `Menu` model.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
// Before saving a value.
|
||||
// Fired before an `insert` or `update` query.
|
||||
// beforeSave: async (model, attrs, options) => {},
|
||||
// After saving a value.
|
||||
// Fired after an `insert` or `update` query.
|
||||
// afterSave: async (model, response, options) => {},
|
||||
// Before fetching a value.
|
||||
// Fired before a `fetch` operation.
|
||||
// beforeFetch: async (model, columns, options) => {},
|
||||
// After fetching a value.
|
||||
// Fired after a `fetch` operation.
|
||||
// afterFetch: async (model, response, options) => {},
|
||||
// Before fetching all values.
|
||||
// Fired before a `fetchAll` operation.
|
||||
// beforeFetchAll: async (model, columns, options) => {},
|
||||
// After fetching all values.
|
||||
// Fired after a `fetchAll` operation.
|
||||
// afterFetchAll: async (model, response, options) => {},
|
||||
// Before creating a value.
|
||||
// Fired before an `insert` query.
|
||||
// beforeCreate: async (model, attrs, options) => {},
|
||||
// After creating a value.
|
||||
// Fired after an `insert` query.
|
||||
// afterCreate: async (model, attrs, options) => {},
|
||||
// Before updating a value.
|
||||
// Fired before an `update` query.
|
||||
// beforeUpdate: async (model, attrs, options) => {},
|
||||
// After updating a value.
|
||||
// Fired after an `update` query.
|
||||
// afterUpdate: async (model, attrs, options) => {},
|
||||
// Before destroying a value.
|
||||
// Fired before a `delete` query.
|
||||
// beforeDestroy: async (model, attrs, options) => {},
|
||||
// After destroying a value.
|
||||
// Fired after a `delete` query.
|
||||
// afterDestroy: async (model, attrs, options) => {}
|
||||
};
|
||||
module.exports = {};
|
||||
|
||||
@ -4,41 +4,4 @@
|
||||
* Lifecycle callbacks for the `Menusection` model.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
// Before saving a value.
|
||||
// Fired before an `insert` or `update` query.
|
||||
// beforeSave: async (model, attrs, options) => {},
|
||||
// After saving a value.
|
||||
// Fired after an `insert` or `update` query.
|
||||
// afterSave: async (model, response, options) => {},
|
||||
// Before fetching a value.
|
||||
// Fired before a `fetch` operation.
|
||||
// beforeFetch: async (model, columns, options) => {},
|
||||
// After fetching a value.
|
||||
// Fired after a `fetch` operation.
|
||||
// afterFetch: async (model, response, options) => {},
|
||||
// Before fetching all values.
|
||||
// Fired before a `fetchAll` operation.
|
||||
// beforeFetchAll: async (model, columns, options) => {},
|
||||
// After fetching all values.
|
||||
// Fired after a `fetchAll` operation.
|
||||
// afterFetchAll: async (model, response, options) => {},
|
||||
// Before creating a value.
|
||||
// Fired before an `insert` query.
|
||||
// beforeCreate: async (model, attrs, options) => {},
|
||||
// After creating a value.
|
||||
// Fired after an `insert` query.
|
||||
// afterCreate: async (model, attrs, options) => {},
|
||||
// Before updating a value.
|
||||
// Fired before an `update` query.
|
||||
// beforeUpdate: async (model, attrs, options) => {},
|
||||
// After updating a value.
|
||||
// Fired after an `update` query.
|
||||
// afterUpdate: async (model, attrs, options) => {},
|
||||
// Before destroying a value.
|
||||
// Fired before a `delete` query.
|
||||
// beforeDestroy: async (model, attrs, options) => {},
|
||||
// After destroying a value.
|
||||
// Fired after a `delete` query.
|
||||
// afterDestroy: async (model, attrs, options) => {}
|
||||
};
|
||||
module.exports = {};
|
||||
|
||||
@ -5,40 +5,54 @@
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
// Before saving a value.
|
||||
// Fired before an `insert` or `update` query.
|
||||
// beforeSave: async (model, attrs, options) => {},
|
||||
// After saving a value.
|
||||
// Fired after an `insert` or `update` query.
|
||||
// afterSave: async (model, response, options) => {},
|
||||
// Before fetching a value.
|
||||
// Fired before a `fetch` operation.
|
||||
// beforeFetch: async (model, columns, options) => {},
|
||||
// After fetching a value.
|
||||
// Fired after a `fetch` operation.
|
||||
// afterFetch: async (model, response, options) => {},
|
||||
// Before fetching all values.
|
||||
// Fired before a `fetchAll` operation.
|
||||
// beforeFetchAll: async (model, columns, options) => {},
|
||||
// After fetching all values.
|
||||
// Fired after a `fetchAll` operation.
|
||||
// afterFetchAll: async (model, response, options) => {},
|
||||
// Before creating a value.
|
||||
// Fired before an `insert` query.
|
||||
// beforeCreate: async (model, attrs, options) => {},
|
||||
// After creating a value.
|
||||
// Fired after an `insert` query.
|
||||
// afterCreate: async (model, attrs, options) => {},
|
||||
// Before updating a value.
|
||||
// Fired before an `update` query.
|
||||
// beforeUpdate: async (model, attrs, options) => {},
|
||||
// After updating a value.
|
||||
// Fired after an `update` query.
|
||||
// afterUpdate: async (model, attrs, options) => {},
|
||||
// Before destroying a value.
|
||||
// Fired before a `delete` query.
|
||||
// beforeDestroy: async (model, attrs, options) => {},
|
||||
// After destroying a value.
|
||||
// Fired after a `delete` query.
|
||||
// afterDestroy: async (model, attrs, options) => {}
|
||||
lifecycles: {
|
||||
beforeCreate(...args) {
|
||||
// console.log('beforeCreate', ...args);
|
||||
},
|
||||
afterCreate(...args) {
|
||||
// console.log('afterCreate', ...args);
|
||||
},
|
||||
beforeUpdate(...args) {
|
||||
// console.log('beforeUpdate', ...args);
|
||||
},
|
||||
afterUpdate(...args) {
|
||||
// console.log('afterUpdate', ...args);
|
||||
},
|
||||
beforeDelete(...args) {
|
||||
// console.log('beforeDelete', ...args);
|
||||
},
|
||||
afterDelete(...args) {
|
||||
// console.log('afterDelete', ...args);
|
||||
},
|
||||
beforeFind(...args) {
|
||||
// console.log('beforeFind', ...args);
|
||||
},
|
||||
afterFind(...args) {
|
||||
// console.log('afterFind', ...args);
|
||||
},
|
||||
beforeFindOne(...args) {
|
||||
// console.log('beforeFindOne', ...args);
|
||||
},
|
||||
afterFindOne(...args) {
|
||||
// console.log('afterFindOne', ...args);
|
||||
},
|
||||
beforeCount(...args) {
|
||||
// console.log('beforeCount', ...args);
|
||||
},
|
||||
afterCount(...args) {
|
||||
// console.log('afterCount', ...args);
|
||||
},
|
||||
beforeSearch(...args) {
|
||||
// console.log('beforeSearch', ...args);
|
||||
},
|
||||
afterSearch(...args) {
|
||||
// console.log('afterSearch', ...args);
|
||||
},
|
||||
beforeCountSearch(...args) {
|
||||
// console.log('beforeCountSearch', ...args);
|
||||
},
|
||||
afterCountSearch(...args) {
|
||||
// console.log('afterCountSearch', ...args);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@ -4,41 +4,4 @@
|
||||
* Lifecycle callbacks for the `Review` model.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
// Before saving a value.
|
||||
// Fired before an `insert` or `update` query.
|
||||
// beforeSave: async (model, attrs, options) => {},
|
||||
// After saving a value.
|
||||
// Fired after an `insert` or `update` query.
|
||||
// afterSave: async (model, response, options) => {},
|
||||
// Before fetching a value.
|
||||
// Fired before a `fetch` operation.
|
||||
// beforeFetch: async (model, columns, options) => {},
|
||||
// After fetching a value.
|
||||
// Fired after a `fetch` operation.
|
||||
// afterFetch: async (model, response, options) => {},
|
||||
// Before fetching all values.
|
||||
// Fired before a `fetchAll` operation.
|
||||
// beforeFetchAll: async (model, columns, options) => {},
|
||||
// After fetching all values.
|
||||
// Fired after a `fetchAll` operation.
|
||||
// afterFetchAll: async (model, response, options) => {},
|
||||
// Before creating a value.
|
||||
// Fired before an `insert` query.
|
||||
// beforeCreate: async (model, attrs, options) => {},
|
||||
// After creating a value.
|
||||
// Fired after an `insert` query.
|
||||
// afterCreate: async (model, attrs, options) => {},
|
||||
// Before updating a value.
|
||||
// Fired before an `update` query.
|
||||
// beforeUpdate: async (model, attrs, options) => {},
|
||||
// After updating a value.
|
||||
// Fired after an `update` query.
|
||||
// afterUpdate: async (model, attrs, options) => {},
|
||||
// Before destroying a value.
|
||||
// Fired before a `delete` query.
|
||||
// beforeDestroy: async (model, attrs, options) => {},
|
||||
// After destroying a value.
|
||||
// Fired after a `delete` query.
|
||||
// afterDestroy: async (model, attrs, options) => {}
|
||||
};
|
||||
module.exports = {};
|
||||
|
||||
@ -1,10 +0,0 @@
|
||||
{
|
||||
"favicon": {
|
||||
"path": "favicon.ico",
|
||||
"maxAge": 86400000
|
||||
},
|
||||
"public": {
|
||||
"path": "./public",
|
||||
"maxAge": 60000
|
||||
}
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
{
|
||||
"myCustomConfiguration": "This configuration is accessible through strapi.config.myCustomConfiguration"
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
{
|
||||
"myCustomConfiguration": "This configuration is accessible through strapi.config.environments.development.myCustomConfiguration"
|
||||
}
|
||||
@ -1,23 +0,0 @@
|
||||
{
|
||||
"session": {
|
||||
"enabled": true,
|
||||
"client": "cookie",
|
||||
"key": "strapi.sid",
|
||||
"prefix": "strapi:sess:",
|
||||
"secretKeys": ["mySecretKey1", "mySecretKey2"],
|
||||
"httpOnly": true,
|
||||
"maxAge": 86400000,
|
||||
"overwrite": true,
|
||||
"signed": false,
|
||||
"rolling": false
|
||||
},
|
||||
"logger": {
|
||||
"level": "debug",
|
||||
"exposeInContext": true,
|
||||
"requests": true
|
||||
},
|
||||
"parser": {
|
||||
"enabled": true,
|
||||
"multipart": true
|
||||
}
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
{
|
||||
"gzip": {
|
||||
"enabled": false
|
||||
},
|
||||
"responseTime": {
|
||||
"enabled": false
|
||||
},
|
||||
"poweredBy": {
|
||||
"enabled": true,
|
||||
"value": "Strapi <strapi.io>"
|
||||
}
|
||||
}
|
||||
@ -1,31 +0,0 @@
|
||||
{
|
||||
"csp": {
|
||||
"enabled": true,
|
||||
"policy": ["block-all-mixed-content"]
|
||||
},
|
||||
"p3p": {
|
||||
"enabled": false,
|
||||
"value": ""
|
||||
},
|
||||
"hsts": {
|
||||
"enabled": true,
|
||||
"maxAge": 31536000,
|
||||
"includeSubDomains": true
|
||||
},
|
||||
"xframe": {
|
||||
"enabled": true,
|
||||
"value": "SAMEORIGIN"
|
||||
},
|
||||
"xss": {
|
||||
"enabled": true,
|
||||
"mode": "block"
|
||||
},
|
||||
"cors": {
|
||||
"enabled": true
|
||||
},
|
||||
"ip": {
|
||||
"enabled": false,
|
||||
"whiteList": [],
|
||||
"blackList": []
|
||||
}
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
{
|
||||
"host": "${process.env.HOST || '0.0.0.0'}",
|
||||
"port": "${process.env.PORT || 1337}",
|
||||
"proxy": {
|
||||
"enabled": false
|
||||
},
|
||||
"cron": {
|
||||
"enabled": false
|
||||
},
|
||||
"admin": {
|
||||
"autoOpen": false
|
||||
}
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
{
|
||||
"myCustomConfiguration": "This configuration is accessible through strapi.config.environments.production.myCustomConfiguration"
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
{
|
||||
"defaultConnection": "default",
|
||||
"connections": {
|
||||
"default": {
|
||||
"connector": "bookshelf",
|
||||
"settings": {
|
||||
"client": "sqlite",
|
||||
"host": "${process.env.DATABASE_HOST || '127.0.0.1'}",
|
||||
"port": "${process.env.DATABASE_PORT || 27017}",
|
||||
"database": "${process.env.DATABASE_NAME || 'strapi'}",
|
||||
"username": "${process.env.DATABASE_USERNAME || ''}",
|
||||
"password": "${process.env.DATABASE_PASSWORD || ''}"
|
||||
},
|
||||
"options": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,23 +0,0 @@
|
||||
{
|
||||
"session": {
|
||||
"enabled": true,
|
||||
"client": "cookie",
|
||||
"key": "strapi.sid",
|
||||
"prefix": "strapi:sess:",
|
||||
"secretKeys": ["mySecretKey1", "mySecretKey2"],
|
||||
"httpOnly": true,
|
||||
"maxAge": 86400000,
|
||||
"overwrite": true,
|
||||
"signed": false,
|
||||
"rolling": false
|
||||
},
|
||||
"logger": {
|
||||
"level": "info",
|
||||
"exposeInContext": true,
|
||||
"requests": false
|
||||
},
|
||||
"parser": {
|
||||
"enabled": true,
|
||||
"multipart": true
|
||||
}
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
{
|
||||
"gzip": {
|
||||
"enabled": true
|
||||
},
|
||||
"responseTime": {
|
||||
"enabled": false
|
||||
},
|
||||
"poweredBy": {
|
||||
"enabled": true,
|
||||
"value": "Strapi <strapi.io>"
|
||||
}
|
||||
}
|
||||
@ -1,31 +0,0 @@
|
||||
{
|
||||
"csp": {
|
||||
"enabled": true,
|
||||
"policy": ["block-all-mixed-content"]
|
||||
},
|
||||
"p3p": {
|
||||
"enabled": true,
|
||||
"value": ""
|
||||
},
|
||||
"hsts": {
|
||||
"enabled": true,
|
||||
"maxAge": 31536000,
|
||||
"includeSubDomains": true
|
||||
},
|
||||
"xframe": {
|
||||
"enabled": true,
|
||||
"value": "SAMEORIGIN"
|
||||
},
|
||||
"xss": {
|
||||
"enabled": true,
|
||||
"mode": "block"
|
||||
},
|
||||
"cors": {
|
||||
"enabled": true
|
||||
},
|
||||
"ip": {
|
||||
"enabled": false,
|
||||
"whiteList": [],
|
||||
"blackList": []
|
||||
}
|
||||
}
|
||||
@ -1,14 +0,0 @@
|
||||
{
|
||||
"host": "${process.env.HOST || '0.0.0.0'}",
|
||||
"port": "${process.env.PORT || 1337}",
|
||||
"production": true,
|
||||
"proxy": {
|
||||
"enabled": false
|
||||
},
|
||||
"cron": {
|
||||
"enabled": false
|
||||
},
|
||||
"admin": {
|
||||
"autoOpen": false
|
||||
}
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
{
|
||||
"myCustomConfiguration": "This configuration is accessible through strapi.config.environments.staging.myCustomConfiguration"
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
{
|
||||
"defaultConnection": "default",
|
||||
"connections": {
|
||||
"default": {
|
||||
"connector": "bookshelf",
|
||||
"settings": {
|
||||
"client": "sqlite",
|
||||
"host": "${process.env.DATABASE_HOST || '127.0.0.1'}",
|
||||
"port": "${process.env.DATABASE_PORT || 27017}",
|
||||
"database": "${process.env.DATABASE_NAME || 'strapi'}",
|
||||
"username": "${process.env.DATABASE_USERNAME || ''}",
|
||||
"password": "${process.env.DATABASE_PASSWORD || ''}"
|
||||
},
|
||||
"options": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,23 +0,0 @@
|
||||
{
|
||||
"session": {
|
||||
"enabled": true,
|
||||
"client": "cookie",
|
||||
"key": "strapi.sid",
|
||||
"prefix": "strapi:sess:",
|
||||
"secretKeys": ["mySecretKey1", "mySecretKey2"],
|
||||
"httpOnly": true,
|
||||
"maxAge": 86400000,
|
||||
"overwrite": true,
|
||||
"signed": false,
|
||||
"rolling": false
|
||||
},
|
||||
"logger": {
|
||||
"level": "info",
|
||||
"exposeInContext": true,
|
||||
"requests": false
|
||||
},
|
||||
"parser": {
|
||||
"enabled": true,
|
||||
"multipart": true
|
||||
}
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
{
|
||||
"gzip": {
|
||||
"enabled": true
|
||||
},
|
||||
"responseTime": {
|
||||
"enabled": false
|
||||
},
|
||||
"poweredBy": {
|
||||
"enabled": true,
|
||||
"value": "Strapi <strapi.io>"
|
||||
}
|
||||
}
|
||||
@ -1,31 +0,0 @@
|
||||
{
|
||||
"csp": {
|
||||
"enabled": true,
|
||||
"policy": ["block-all-mixed-content"]
|
||||
},
|
||||
"p3p": {
|
||||
"enabled": true,
|
||||
"value": ""
|
||||
},
|
||||
"hsts": {
|
||||
"enabled": true,
|
||||
"maxAge": 31536000,
|
||||
"includeSubDomains": true
|
||||
},
|
||||
"xframe": {
|
||||
"enabled": true,
|
||||
"value": "SAMEORIGIN"
|
||||
},
|
||||
"xss": {
|
||||
"enabled": true,
|
||||
"mode": "block"
|
||||
},
|
||||
"cors": {
|
||||
"enabled": true
|
||||
},
|
||||
"ip": {
|
||||
"enabled": false,
|
||||
"whiteList": [],
|
||||
"blackList": []
|
||||
}
|
||||
}
|
||||
@ -1,14 +0,0 @@
|
||||
{
|
||||
"host": "${process.env.HOST || '0.0.0.0'}",
|
||||
"port": "${process.env.PORT || 1337}",
|
||||
"production": true,
|
||||
"proxy": {
|
||||
"enabled": false
|
||||
},
|
||||
"cron": {
|
||||
"enabled": false
|
||||
},
|
||||
"admin": {
|
||||
"autoOpen": false
|
||||
}
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
{
|
||||
"timeout": 3000,
|
||||
"load": {
|
||||
"before": [],
|
||||
"order": [],
|
||||
"after": []
|
||||
}
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
{
|
||||
"enabled": true,
|
||||
"defaultLocale": "en_us",
|
||||
"modes": [
|
||||
"query",
|
||||
"subdomain",
|
||||
"cookie",
|
||||
"header",
|
||||
"url",
|
||||
"tld"
|
||||
],
|
||||
"cookieName": "locale"
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
{
|
||||
"welcome": "Vítejte"
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
{
|
||||
"welcome": "Welcome"
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
{
|
||||
"welcome": "Bienvenido"
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
{
|
||||
"welcome": "Bienvenue"
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
{
|
||||
"welcome": "Benvenuto"
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
{
|
||||
"welcome": "ようこそ"
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
{
|
||||
"welcome": "Добро пожаловать"
|
||||
}
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
{
|
||||
"welcome": "Hoşgeldin"
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
{
|
||||
"welcome": "Chào mừng"
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
{
|
||||
"timeout": 100,
|
||||
"load": {
|
||||
"before": [
|
||||
"responseTime",
|
||||
"logger",
|
||||
"cors",
|
||||
"responses",
|
||||
"gzip"
|
||||
],
|
||||
"order": [
|
||||
"session", "xframe", "public"
|
||||
],
|
||||
"after": [
|
||||
"parser",
|
||||
"router"
|
||||
]
|
||||
}
|
||||
}
|
||||
6
examples/getstarted/config/plugins.js
Normal file
6
examples/getstarted/config/plugins.js
Normal file
@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
graphql: {
|
||||
amountLimit: 5,
|
||||
depthLimit: 10,
|
||||
},
|
||||
};
|
||||
4
examples/getstarted/config/server.js
Normal file
4
examples/getstarted/config/server.js
Normal file
@ -0,0 +1,4 @@
|
||||
module.exports = ({ env }) => ({
|
||||
host: env('HOST', '0.0.0.0'),
|
||||
port: env.int('PORT', 1337),
|
||||
});
|
||||
@ -1,4 +0,0 @@
|
||||
{
|
||||
"amountLimit": 5,
|
||||
"depthLimit": 10
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
jwtSecret: process.env.JWT_SECRET || 'c98f7e9c-dc1d-4ee1-a380-53c3a7125a7e',
|
||||
};
|
||||
@ -1,3 +0,0 @@
|
||||
{
|
||||
"jwtSecret": "bb26b371-8957-434c-a313-f35dd6b1813c"
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "getstarted",
|
||||
"private": true,
|
||||
"version": "3.0.0-beta.20",
|
||||
"version": "3.0.0-beta.20.3",
|
||||
"description": "A Strapi application.",
|
||||
"scripts": {
|
||||
"develop": "strapi develop",
|
||||
@ -15,22 +15,22 @@
|
||||
"mysql": "^2.17.1",
|
||||
"pg": "^7.10.0",
|
||||
"sqlite3": "^4.0.6",
|
||||
"strapi": "3.0.0-beta.20",
|
||||
"strapi-admin": "3.0.0-beta.20",
|
||||
"strapi-connector-bookshelf": "3.0.0-beta.20",
|
||||
"strapi-connector-mongoose": "3.0.0-beta.20",
|
||||
"strapi-middleware-views": "3.0.0-beta.20",
|
||||
"strapi-plugin-content-manager": "3.0.0-beta.20",
|
||||
"strapi-plugin-content-type-builder": "3.0.0-beta.20",
|
||||
"strapi-plugin-documentation": "3.0.0-beta.20",
|
||||
"strapi-plugin-email": "3.0.0-beta.20",
|
||||
"strapi-plugin-graphql": "3.0.0-beta.20",
|
||||
"strapi-plugin-upload": "3.0.0-beta.20",
|
||||
"strapi-plugin-users-permissions": "3.0.0-beta.20",
|
||||
"strapi-provider-email-mailgun": "3.0.0-beta.20",
|
||||
"strapi-provider-upload-aws-s3": "3.0.0-beta.20",
|
||||
"strapi-provider-upload-cloudinary": "3.0.0-beta.20",
|
||||
"strapi-utils": "3.0.0-beta.20"
|
||||
"strapi": "3.0.0-beta.20.3",
|
||||
"strapi-admin": "3.0.0-beta.20.3",
|
||||
"strapi-connector-bookshelf": "3.0.0-beta.20.3",
|
||||
"strapi-connector-mongoose": "3.0.0-beta.20.3",
|
||||
"strapi-middleware-views": "3.0.0-beta.20.3",
|
||||
"strapi-plugin-content-manager": "3.0.0-beta.20.3",
|
||||
"strapi-plugin-content-type-builder": "3.0.0-beta.20.3",
|
||||
"strapi-plugin-documentation": "3.0.0-beta.20.3",
|
||||
"strapi-plugin-email": "3.0.0-beta.20.3",
|
||||
"strapi-plugin-graphql": "3.0.0-beta.20.3",
|
||||
"strapi-plugin-upload": "3.0.0-beta.20.3",
|
||||
"strapi-plugin-users-permissions": "3.0.0-beta.20.3",
|
||||
"strapi-provider-email-mailgun": "3.0.0-beta.20.3",
|
||||
"strapi-provider-upload-aws-s3": "3.0.0-beta.20.3",
|
||||
"strapi-provider-upload-cloudinary": "3.0.0-beta.20.3",
|
||||
"strapi-utils": "3.0.0-beta.20.3"
|
||||
},
|
||||
"strapi": {
|
||||
"uuid": "getstarted"
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "3.0.0-beta.20",
|
||||
"version": "3.0.0-beta.20.3",
|
||||
"packages": [
|
||||
"packages/*",
|
||||
"examples/*"
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"private": true,
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@babel/plugin-transform-modules-commonjs": "^7.8.3",
|
||||
"@babel/plugin-transform-modules-commonjs": "^7.9.0",
|
||||
"@testing-library/jest-dom": "^4.0.0",
|
||||
"@testing-library/react": "^9.1.0",
|
||||
"@testing-library/react-hooks": "^2.0.0",
|
||||
@ -40,6 +40,10 @@
|
||||
"request-promise-native": "^1.0.7",
|
||||
"rimraf": "3.0.0",
|
||||
"snyk": "^1.99.0",
|
||||
"stylelint": "10.0.1",
|
||||
"stylelint-config-recommended": "2.2.0",
|
||||
"stylelint-config-styled-components": "0.1.1",
|
||||
"stylelint-processor-styled-components": "1.6.0",
|
||||
"wait-on": "^3.2.0",
|
||||
"yargs": "^13.2.2"
|
||||
},
|
||||
@ -47,8 +51,9 @@
|
||||
"setup": "yarn && yarn build",
|
||||
"watch": "lerna run --stream watch --no-private",
|
||||
"build": "lerna run --stream build --no-private",
|
||||
"lint": "npm-run-all -p lint:code",
|
||||
"lint": "npm-run-all -p lint:code lint:css",
|
||||
"lint:code": "eslint .",
|
||||
"lint:css": "stylelint packages/**/admin/src/**/**/*.js",
|
||||
"lint:fix": "eslint --fix .",
|
||||
"lint:other": "npm run prettier:other -- --check",
|
||||
"format": "npm-run-all -p format:*",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "create-strapi-app",
|
||||
"version": "3.0.0-beta.20",
|
||||
"version": "3.0.0-beta.20.3",
|
||||
"description": "Generate a new Strapi application.",
|
||||
"license": "MIT",
|
||||
"homepage": "http://strapi.io",
|
||||
@ -21,7 +21,7 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"commander": "^2.20.0",
|
||||
"strapi-generate-new": "3.0.0-beta.20"
|
||||
"strapi-generate-new": "3.0.0-beta.20.3"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"no tests yet\""
|
||||
|
||||
@ -18,7 +18,6 @@ import '@babel/polyfill';
|
||||
import 'sanitize.css/sanitize.css';
|
||||
|
||||
// Third party css library needed
|
||||
import 'react-datetime/css/react-datetime.css';
|
||||
import 'bootstrap/dist/css/bootstrap.css';
|
||||
import 'font-awesome/css/font-awesome.min.css';
|
||||
import '@fortawesome/fontawesome-free/css/all.css';
|
||||
@ -36,6 +35,7 @@ import { freezeApp, pluginLoaded, unfreezeApp, updatePlugin } from './containers
|
||||
import { showNotification } from './containers/NotificationProvider/actions';
|
||||
|
||||
import basename from './utils/basename';
|
||||
import getInjectors from './utils/reducerInjectors';
|
||||
import injectReducer from './utils/injectReducer';
|
||||
import injectSaga from './utils/injectSaga';
|
||||
import Strapi from './utils/Strapi';
|
||||
@ -95,6 +95,13 @@ Object.keys(plugins).forEach(current => {
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
// Inject plugins reducers
|
||||
const pluginReducers = plugin.reducers || {};
|
||||
|
||||
Object.keys(pluginReducers).forEach(reducerName => {
|
||||
getInjectors(store).injectReducer(reducerName, pluginReducers[reducerName]);
|
||||
});
|
||||
|
||||
try {
|
||||
merge(translationMessages, pluginTradsPrefixed);
|
||||
dispatch(pluginLoaded(plugin));
|
||||
@ -189,24 +196,7 @@ if (module.hot) {
|
||||
}
|
||||
|
||||
if (NODE_ENV !== 'test') {
|
||||
// Chunked polyfill for browsers without Intl support
|
||||
if (!window.Intl) {
|
||||
new Promise(resolve => {
|
||||
resolve(import('intl'));
|
||||
})
|
||||
.then(() =>
|
||||
Promise.all([
|
||||
import('intl/locale-data/jsonp/en.js'),
|
||||
import('intl/locale-data/jsonp/de.js'),
|
||||
])
|
||||
)
|
||||
.then(() => render(translationMessages))
|
||||
.catch(err => {
|
||||
throw err;
|
||||
});
|
||||
} else {
|
||||
render(translationMessages);
|
||||
}
|
||||
render(translationMessages);
|
||||
}
|
||||
|
||||
// @Pierre Burgy exporting dispatch for the notifications...
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.2 KiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user