Custom Plugin: Component and Content-Type creation by startup

System Information
  • Strapi Version: 4.13.4
  • Operating System: macOS
  • Database: sqlite
  • Node Version: v18.17.0
  • NPM Version: 9.6.7
  • Yarn Version: -

Hi all,

I am currently working more intensively on plugin development and am facing a small problem:

My plugin has several components and content types. Content types are created correctly and automatically when starting. Components, on the other hand, have to be created manually, as with the Strapi SEO plugin (Create components using a plugin). I do this within register.js so that I can react to updates within the schemas before initialising strapi. If I create or update the components, I restart the server using strapi.reload().

Now this is my problem:
Sometimes the plugin creates collection types before the creation of components is done. I want to make sure that the creation of all components is finished and after that the plugin should begin creating collection types.

Is that even possible or is there another way to solve this?

Best regards

2 Likes

Hey @codemaniac,

I am also struggling to find the way how Strapi wants us plugin-developers to create (and bring along) components with our plugin.

Without that created content-Types are quite dumb.

I know @Boegie19 is a busy man but maybe you know how it’s possible to create a plugin with some plugin-related components.

Or are there any (near) future plans to improve creating plugin in the direction of components?
Because refactor(core/strapi): move components to registry by iamandrewluca · Pull Request #16273 · strapi/strapi · GitHub does sadly not sound like that so we might have to wait until v5? :frowning: @Mcastres

1 Like

You can create components. but not trough the file system with plugins. if you go into yarn strapi console and type in strapi.components you see a list of all components. you can in the register faze of your plugin do strapi.components.push({object same format as all the others}) and it will register the component for you.

sorry for the late responce

Thank you @Boegie19 .
But if I try to use strapi.components.push(...) within bootstrap.js or register.js, the server no longer starts: strapi.components.push is not a function

strapi.components is an object not an array that is my mistake so it shoud be so it is.
strapi.components[“sectionName.ComponentName”] = {}

The server starts but the components are neither visible in the DB nor in the admin interface. :frowning:
For now, I’m copying the components into the strapi directories using npm until there is an official way from strapi.

Components inside of plugins | Developer Experience | Strapi > hopefully :slight_smile:

If you do it inside of register it should work.

I correct you are right in the database the component appears correctly. As soon as I switch to the Content Type Builder in the admin, only a white page appears. When I restart the server, it no longer starts up with the following message:

TypeError: Cannot read properties of undefined (reading 'attributes')
  const data = {
    collectionName: "components_test_bars",
    info: {
      displayName: "bar",
    },
    options: {},
    attributes: {
      foo: {
        type: "string",
      },
    },
  };
  strapi.components["test.bars"] = data;

since you are missing a part of the data it expects.

try runing strapi.components for an existing component with yarn strapi console then you see what it expects

Okay - but the error message is confusing.

I add the additional variables like:

  • category
  • modelName
  • globalId
  • uid

and name the component “test.bar” instead of “test.bars”.

const data = {
    collectionName: "components_test_bars",
    category: "test",
    modelName: "bar",
    globalId: "ComponentTestBar",
    uid: "test.bar",
    info: {
      displayName: "bar",
    },
    options: {},
    attributes: {
      foo: {
        type: "string",
      },
    },
  };
  strapi.components["test.bar"] = data;

Now it’s working! :slight_smile:
Thank you @Boegie19

1 Like

It is since you are doing someting advanced outside of the normal user routes.

I’m using Strapi 4.14.5 and I writing my plugin with Typescript. The object strapi.components[“uid”] expect the type Schema.Component. The type does not provide all attrbiutes for the component to be accepted. I had to add info, filename and schema for it to work. I also have to specify a filename even though i don’t have a file.

Thank you @Boegie19 for your hint with the strapi console.

import { Strapi } from "@strapi/strapi";

export default async ({ strapi }: { strapi: Strapi }) => {
  const schema = {
    collectionName: "components_huhu_minis",
    info: { displayName: "mini", icon: "alien" },
    options: {},
    attributes: { attribut1: { type: "string" } },
    __filename__: "mini.json",
    __schema__: {
      collectionName: "components_huhu_minis",
      info: { displayName: "mini", icon: "alien" },
      options: {},
      attributes: { attribut1: { type: "string" } },
      __filename__: "mini.json",
    },
    uid: "huhu.mini",
    category: "huhu",
    modelType: "component",
    modelName: "mini",
    globalId: "ComponentHuhuMini",
  };

  strapi.components["huhu.mini"] = schema as any;
};

I created a bug report Custom Plugin - Register Component - Typescript · Issue #18724 · strapi/strapi · GitHub