How to create a custom field programmatically on content type creation? I have a module which creates custom fields to the selected content type. This works fine when the content type already exists.

With hook_form_node_type_form_alter I create a extra tab on the edit page of the content type. In this tab is a simple checkbox.

function hook_seo_form_node_type_form_alter(&amp;$form)
{
    /* @ CREATE VERTICAL TAB ON CONTENT TYPE TO ADD OR REMOVE SEO  */
    //get node type
    $bundle = $form['type']['#default_value'];
    if ($bundle != null) {
        $node_type = NodeType::load($bundle);
        $default_value = $node_type-&gt;getThirdPartySetting('seo', 'seo_options');
    } else {
        $default_value = 0;
    }

    //create vertical tab
    $form['seo'] = array(
        '#type' =&gt; 'details',
        '#title' =&gt; t('SEO'),
        '#group' =&gt; 'additional_settings',
    );

    //add checkbox to vertical tab
    $form['seo']['seo_options'] = array(
        '#type' =&gt; 'checkbox',
        '#title' =&gt; t('Use custom SEO fields'),
        '#collapsible' =&gt; TRUE,
        '#collapsed' =&gt; TRUE,
        '#weight' =&gt; 10,
        '#default_value' =&gt; $default_value,
    );

    //create submit handler
    $form['actions']['submit']['#submit'][] = 'seo_form_submit';
}


I use  the following function to see if the form of the content type is submitted and run my script to add fields. 

function seo_form_submit(&amp;$form, \Drupal\Core\Form\FormStateInterface $form_state)
{
    /* @ ON SUBMIT SAVE CONFIG &amp; ADD/REMOVE FIELDS  */
    //get node type
    $bundle = $form['type']['#default_value'];
    $node_type = NodeType::load($bundle);
    $checkbox = $form['seo']['seo_options']['#value'];

    //set checkbox value to config and save
    $node_type-&gt;setThirdPartySetting('seo', 'seo_options', $checkbox);
    $node_type-&gt;save();


    if ($checkbox == 1) {
        //Add fields
        seo_enable_field(
            'add',
            'node',
            $bundle,
            'page_title',
            'string_textfield',
            'basic_string',
            'Page title',
            'Description'
        );
    }


But for some reason this only works when the content type already exist and I edit it. When I create a new content type it doesn't work and my fields are not created.

How can I solve this?
It is the NodeType::load() in seo_form_submit() that is failing because the bundle doesn't exist at the time the form is submitted for the first time.

My recommendation would be to redesign this code so that the logic to create/destroy the field is in both a hook_node_type_insert() and a hook_node_type_update().

You will need some way to pass the value of the checkbox on the form to these respective hooks. Most likely through a custom configuration or schema.

Edit: It looks like there is more than one design pattern that would work as well as the one I recommended in this answer. Please reference Entity CRUD, editing, and view hooks.