How do I disable the default node creation form for a particular node type? I have a node type recipe, which should only ever be created via a custom route that causes it to be linked to a parent food type, ie. if the user visits node/add/recipe/1 they will see a recipe creation form that is linked to node 1 of type food.
Now I want to disable the /node/add/recipe route and prevent the recipe node from appearing on node/add. What's the best way to do this?
Note that this is not just a permissions issue - with my module it simply doesn't make sense for a recipe type to be created without a food that is linked to it, so visiting the node/add/recipe page simply doesn't make sense, even for an administrator.
A different approach would be to deny access by throwing an exception, which also affects admins:
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;

/**
 * Implements hook_form_FORM_ID_alter().
 */
function mymodule_form_node_recipe_form_alter(&amp;$form, FormStateInterface $form_state, $form_id) {
  throw new AccessDeniedHttpException();
}

The Form ID consists of ENTITY_TYPE_BUNDLE_FORM_MODE_form. This assumes you use for your specific recipe form a different form mode.  If not, you can check the reference field value in $form_state-&gt;getFormObject()-&gt;getEntity() before throwing the exception.
By the way, the hook name doesn't contain a form mode because nodes use the form mode default for the add form, which is omitted in the Form ID. The node edit form for example has the form mode edit, so the form alter hook would then be named mymodule_form_node_recipe_edit_form_alter.
Since this approach is not based on entity access permissions it doesn't remove the link from the node add list. You can do this in a separate hook:
/**
 * Implements hook_preprocess_HOOK() for list of available node type templates
 */
function mymodule_preprocess_node_add_list(&amp;$variables) {
  unset($variables['content']['recipe']);
  unset($variables['types']['recipe']);
}