Strapi Local Plugin Development

Written by on September 14, 2021; tagged under strapi

Strapi allows customization to a great extent with the help of local plugins. These plugins can be simple React applications. Generated plugins reside within /plugins folder.

In this post, I am creating a local plugin posts which displays posts from JSONPlaceholder Fake API. Here is the link of the repository for reference.

Create new strapi project by running the following command in terminal:

yarn create strapi-app project-name --quickstart
cd project-name

Generate local plugin you want to build using the command:

yarn strapi generate:plugin posts

New folder /posts is created in /plugins directory. To see this plugin in admin panel, you should run:

yarn build
yarn develop

Now we can see the plugin link in Strapi

screenshot1

This is the directory structure of the generated plugin

posts/
└─── admin/ # Contains the plugin's front-end
|     └─── src/ # Source code directory
|          └─── index.js # Entry point of the plugin
|          └─── pluginId.js # Name of the plugin
|          |
|          └─── components/ # Contains the list of React components used by the plugin
|          └─── containers/
|          |    └─── App/ # Container used by every others containers
|          |    └─── Initializer/ # This container is required to execute the logic soon after the plugin is mounted.
|          └─── translations/ # Contains the translations to make the plugin internationalized
|               └─── en.json
|               └─── index.js # File that exports all the plugin's translations.
|               └─── fr.json
└─── config/ # Contains the configurations of the plugin
|     └─── functions/
|     |    └─── bootstrap.js # Asynchronous bootstrap function that runs before the app gets started
|     └─── policies/ # Folder containing the plugin's policies
|     └─── queries/ # Folder containing the plugin's models queries
|     └─── routes.json # Contains the plugin's API routes
└─── controllers/ # Contains the plugin's API controllers
└─── middlewares/ # Contains the plugin's middlewares
└─── models/ # Contains the plugin's API models
└─── services/ # Contains the plugin's API services

To enable local plugin development run the following command:

yarn develop --watch-admin

We can delete translations folder, if not necessary. We need to set default value of trads to {} in the menu object provided to the plugin, if deleted.

// plugins/posts/admin/src/index.js

const plugin = {
  // other props
  trads: {},
};

By default strapi provides you with /posts ("path": "/") route.

// posts/config/routes.json

"routes": [
    {
      "method": "GET",
      "path": "/",
      "handler": "posts.index",
      "config": {
        "policies": []
      }
    }
  ]

Call third party api from strapi route instead of directly calling it from the components. Retreive back-end URL using strapi.backendURL API to call /posts route.

// posts/admin/src/containers/HomePage/index.js

useEffect(async () => {
  // Avoid this
  const response = await axios.get(`${process.env.JSON_FAKE_API}/posts`);

  // Do this
  const response = await axios.get(`${strapi.backendURL}/posts`);
}, []);

We can customize the response from index function which is the handler specified for /posts route. Call third party api to fetch posts here.

// posts/controllers/posts.js

index: async (ctx) => {
  const response = await axios.get(`${process.env.JSON_FAKE_API}/posts`);
  return response.data;
};

Routing is implemented in App component at /posts/admin/src/conatainers/App/index.js

I am using Buffet.js which is a React Components library used by Strapi to display posts in <Table />

// posts/admin/src/components/Posts/Post.js

const Posts = ({ posts }) => {
  return (
    <div>
      <Table headers={headers} rows={posts} />
    </div>
  );
};

This is how it looks!

screenshot1

Accessing Environment variable in Frontend

Environmental variables in strapi frontend cannot be accessed directly with process.env.VARIABLE. Instead we should set it by customizing webpack config

Create file at project/admin/admin.config.js

module.exports = {
  webpack: (config, webpack) => {
    config.plugins.push(
      new webpack.DefinePlugin({
        ENV_VARIABLES: {
          variable_1: JSON.stringify(process.env.ENV_VARIABLE_1),
        },
      })
    );
    return config;
  },
};

Access it within components:

<p>{ENV_VARIABLES.variable_1}</p>

Happy Learning

If you have any questions or feedback, feel free to drop us a mail at team@codemancers.com.