diff --git a/docs/3.0.0-beta.x/plugin-development/frontend-settings-api.md b/docs/3.0.0-beta.x/plugin-development/frontend-settings-api.md
index 66764c01e6..1927604dbf 100644
--- a/docs/3.0.0-beta.x/plugin-development/frontend-settings-api.md
+++ b/docs/3.0.0-beta.x/plugin-development/frontend-settings-api.md
@@ -191,3 +191,85 @@ export default strapi => {
return strapi.registerPlugin(plugin);
};
```
+
+## Adding a setting into the global section
+
+In order to add a link into the global section of the settings view you need to create a global array containing the links you want to add;
+
+**Path —** `plugins/my-plugin/admin/src/index.js`.
+
+import pluginPkg from '../../package.json';
+// Import the component
+import Settings from './containers/Settings';
+import SettingLink from './components/SettingLink';
+import pluginId from './pluginId';
+
+export default strapi => {
+const pluginDescription =
+pluginPkg.strapi.description || pluginPkg.description;
+
+// Declare the links that will be injected into the settings menu
+const menuSection = {
+id: pluginId,
+title: {
+id: `${pluginId}.foo`,
+defaultMessage: 'Super cool setting',
+},
+links: [
+{
+title: 'Setting page 1',
+to: `${strapi.settingsBaseURL}/${pluginId}/setting1`,
+name: 'setting1',
+},
+{
+title: {
+id: `${pluginId}.bar`,
+defaultMessage: 'Setting page 2',
+},
+to: `${strapi.settingsBaseURL}/${pluginId}/setting2`,
+name: 'setting2',
+},
+],
+};
+
+const plugin = {
+blockerComponent: null,
+blockerComponentProps: {},
+description: pluginDescription,
+icon: pluginPkg.strapi.icon,
+id: pluginId,
+initializer: () => null,
+injectedComponents: [],
+isReady: true,
+leftMenuLinks: [],
+leftMenuSections: [],
+mainComponent: null,
+name: pluginPkg.strapi.name,
+preventComponentRendering: false,
+settings: {
+// Add a link into the global section of the settings view
+global: [
+{
+title: 'Setting link 1',
+to: `${strapi.settingsBaseURL}/setting-link-1`,
+name: 'settingLink1',
+Component: SettingLink,
+// True or false
+exact: false,
+},
+],
+mainComponent: Settings,
+menuSection,
+},
+trads: {},
+};
+
+return strapi.registerPlugin(plugin);
+};
+
+```
+
+::: danger
+It is currently not possible to add a link into another plugin's setting section
+:::
+```
diff --git a/packages/strapi-admin/admin/src/containers/SettingsPage/index.js b/packages/strapi-admin/admin/src/containers/SettingsPage/index.js
index c69aa05b33..7721a34f3c 100644
--- a/packages/strapi-admin/admin/src/containers/SettingsPage/index.js
+++ b/packages/strapi-admin/admin/src/containers/SettingsPage/index.js
@@ -6,29 +6,30 @@
import React, { memo } from 'react';
import { useGlobalContext, LeftMenu, LeftMenuList } from 'strapi-helper-plugin';
-import { get } from 'lodash';
import { Switch, Redirect, Route, useParams } from 'react-router-dom';
-
import EditView from '../Webhooks/EditView';
import ListView from '../Webhooks/ListView';
import SettingDispatcher from './SettingDispatcher';
import Wrapper from './Wrapper';
+import retrieveGlobalLinks from './utils/retrieveGlobalLinks';
+import retrievePluginsMenu from './utils/retrievePluginsMenu';
function SettingsPage() {
const { settingId } = useParams();
const { formatMessage, plugins, settingsBaseURL } = useGlobalContext();
+ // Retrieve the links that will be injected into the global section
+ const globalLinks = retrieveGlobalLinks(plugins);
+ // Create the plugins settings section
+ // Note it is currently not possible to add a link into a plugin section
+ const pluginsMenu = retrievePluginsMenu(plugins);
- const pluginsMenu = Object.keys(plugins).reduce((acc, current) => {
- const pluginMenu = get(plugins, [current, 'settings', 'menuSection'], null);
-
- if (!pluginMenu) {
- return acc;
- }
-
- acc.push(pluginMenu);
-
- return acc;
- }, []);
+ const createdRoutes = globalLinks
+ .map(({ to, Component, exact }) => (
+
+ ))
+ .filter((route, index, refArray) => {
+ return refArray.findIndex(obj => obj.key === route.key) === index;
+ });
const menuItems = [
{
@@ -40,6 +41,7 @@ function SettingsPage() {
to: `${settingsBaseURL}/webhooks`,
name: 'webhooks',
},
+ ...globalLinks,
],
},
...pluginsMenu,
@@ -74,6 +76,7 @@ function SettingsPage() {
path={`${settingsBaseURL}/webhooks/:id`}
component={EditView}
/>
+ {createdRoutes}
{
+ return Object.values(pluginsObj).reduce((acc, current) => {
+ const links = get(current, ['settings', 'global'], null);
+
+ if (links) {
+ for (let i = 0; i < links.length; i++) {
+ acc.push(links[i]);
+ }
+ }
+
+ return acc;
+ }, []);
+};
+
+export default retrieveGlobalLinks;
diff --git a/packages/strapi-admin/admin/src/containers/SettingsPage/utils/retrievePluginsMenu.js b/packages/strapi-admin/admin/src/containers/SettingsPage/utils/retrievePluginsMenu.js
new file mode 100644
index 0000000000..ca703113bc
--- /dev/null
+++ b/packages/strapi-admin/admin/src/containers/SettingsPage/utils/retrievePluginsMenu.js
@@ -0,0 +1,17 @@
+import { get } from 'lodash';
+
+const retrievePluginsMenu = pluginsObj => {
+ return Object.values(pluginsObj).reduce((acc, current) => {
+ const pluginMenu = get(current, ['settings', 'menuSection'], null);
+
+ if (!pluginMenu) {
+ return acc;
+ }
+
+ acc.push(pluginMenu);
+
+ return acc;
+ }, []);
+};
+
+export default retrievePluginsMenu;
diff --git a/packages/strapi-admin/admin/src/containers/SettingsPage/utils/tests/retrieveGlobalLinks.test.js b/packages/strapi-admin/admin/src/containers/SettingsPage/utils/tests/retrieveGlobalLinks.test.js
new file mode 100644
index 0000000000..85509eb280
--- /dev/null
+++ b/packages/strapi-admin/admin/src/containers/SettingsPage/utils/tests/retrieveGlobalLinks.test.js
@@ -0,0 +1,33 @@
+import retrieveGlobalLinks from '../retrieveGlobalLinks';
+
+describe('ADMIN | containers | SettingsPage | utils', () => {
+ describe('retrieveGlobalLinks', () => {
+ it('should return an empty array if there is no plugins', () => {
+ expect(retrieveGlobalLinks({})).toHaveLength(0);
+ });
+
+ it('should return an array of links', () => {
+ const plugins = {
+ test: {
+ settings: {
+ global: [],
+ },
+ },
+ noSettings: {},
+ foo: {
+ settings: {
+ global: ['test'],
+ },
+ },
+ bar: {
+ settings: {
+ global: ['test2'],
+ },
+ },
+ };
+ const expected = ['test', 'test2'];
+
+ expect(retrieveGlobalLinks(plugins)).toEqual(expected);
+ });
+ });
+});
diff --git a/packages/strapi-admin/admin/src/containers/SettingsPage/utils/tests/retrievePluginsMenu.test.js b/packages/strapi-admin/admin/src/containers/SettingsPage/utils/tests/retrievePluginsMenu.test.js
new file mode 100644
index 0000000000..ca0c3d68e7
--- /dev/null
+++ b/packages/strapi-admin/admin/src/containers/SettingsPage/utils/tests/retrievePluginsMenu.test.js
@@ -0,0 +1,33 @@
+import retrievePluginsMenu from '../retrievePluginsMenu';
+
+describe('ADMIN | containers | SettingsPage | utils', () => {
+ describe('retrievePluginsMenu', () => {
+ it('should return an empty array if there is no plugins', () => {
+ expect(retrievePluginsMenu({})).toHaveLength(0);
+ });
+
+ it('should return an array of menu sections', () => {
+ const plugins = {
+ test: {
+ settings: {
+ menuSection: null,
+ },
+ },
+ noSettings: {},
+ foo: {
+ settings: {
+ menuSection: { label: 'test' },
+ },
+ },
+ bar: {
+ settings: {
+ menuSection: { label: 'test2' },
+ },
+ },
+ };
+ const expected = [{ label: 'test' }, { label: 'test2' }];
+
+ expect(retrievePluginsMenu(plugins)).toEqual(expected);
+ });
+ });
+});