Custom Module: new element type index page access Hello I've created a new element type in a module (a web app within Craft) that I'm developing.
I have initially created my models to be craft\db\ActiveRecord and save directly to their tables, but that is not the &quot;craft&quot; way.
I decided to extend from craft\base\Element and do the needful in order to leverage elementindex.html (search, sort, filter), but going to /admin/custom/index gives a &quot;404 Not Found&quot;. Do I need to create my own CustomController.php ?
I did the configuration needed in my Module class, as well as creating the Custom.php and CustomQuery.php according to the documentation here
   // CP Routes
    Event::on(
        UrlManager::class,
        UrlManager::EVENT_REGISTER_CP_URL_RULES,
        function (RegisterUrlRulesEvent $event) {
            $event-&gt;rules['custom'] = '/app-module/custom/index';
        }
    );

    // CP Nav Items
    Event::on(
        Cp::class,
        Cp::EVENT_REGISTER_CP_NAV_ITEMS,
        function (RegisterCpNavItemsEvent $event) {
            $event-&gt;navItems[] = [
                'url' =&gt; 'custom',
                'label' =&gt; 'Custom',
                'icon' =&gt; 'share',
            ];
        }
    );

    // Custom Element Types
    Event::on(Elements::class,
        Elements::EVENT_REGISTER_ELEMENT_TYPES,
        function(RegisterComponentTypesEvent $event) {
            $event-&gt;types[] = Custom::class;
        }
    );
Since this is a module rather than a plugin, you need to register control panel template roots, like so:
  Event::on(
    View::class,
    View::EVENT_REGISTER_CP_TEMPLATE_ROOTS,
    function (RegisterTemplateRootsEvent $e) {
        $e-&gt;roots['app-module'] = __DIR__ . '/templates/cp';
    }
  );

(I've swapped 'custom' for 'app-module' as I think it's a little more clear, but feel free to keep it as 'custom') If your module's src folder does not have a templates/cp directory, create one and add an index.twig to it. Now going to admin/app-module should load the index file you've created. (You'll need to update the EVENT_REGISTER_CP_NAV_ITEMS from 'custom' to 'app-module' to have the CP url match the change I've made here.) However, since you're working with an element, it's probably better to create another directory named after your element. Let's use &quot;Item&quot; as a generic element class name, you might have templates/cp/items/index.twig who's contents might look like this:
{% extends elementType is defined ? '_layouts/elementindex' : '_layouts/cp' %}

{% set elementType = 'modules\\appmodule\\elements\\ItemElement' %}
{% set title = 'My Custom Items'|t('app-module') %}

{% block actionButton %}
 &lt;div id=&quot;extra-headers&quot;&gt;
    &lt;div class=&quot;buttons right&quot;&gt;
      &lt;a href=&quot;{{ url('app-module/items/new') }}&quot; class=&quot;btn submit add icon&quot;&gt;
       {{ &quot;New custom item&quot;|t('app-module')}}
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
{% endblock %}

You don't need to register this URL via the EVENT_REGISTER_CP_URL_RULES, but you will want to for the element edit and creation page. e.g.
Event::on(
    UrlManager::class,
    UrlManager::EVENT_REGISTER_CP_URL_RULES,
    function (RegisterUrlRulesEvent $event) {
        $event-&gt;rules['app-module/items/new'] = 'app-module/items/edit-item';
        $event-&gt;rules['app-module/items/&lt;itemId:\d+&gt;' =&gt; 'app-module/items/edit-item']
    }
);

Here, the key is the URL you will hit in the control panel and the value is the action URL you'll need to create in your module. src/controllers/ItemsController.php, which will have an actionEditItem function.
Hope this helps!