Automatically add product_categories to nav_menu

put this on your functions.php and then call the function in whatever page desired. this code is prepare to use css.

if (! function_exists('menu_categories')) {
  function menu_categories(){
    $cat_args = array( 'orderby' => 'name', 'order' => 'asc', 'hide_empty' => true);
    $cats = get_terms( 'product_cat', $cat_args ); ?>
    <h1>Categories</h1><?php
    foreach ($cats as $key => $cat):
      if ($cat->parent == 0): ?>
        <div class="tc-menuint-1">
          <a href="<?php echo get_term_link($cat) ?>"><?php echo $cat->name; ?></a></li>
          <div class="tc-menuint-2"><?php
            foreach ($cats as $key => $cat2):
              if ($cat2->parent == $cat->term_id): ?>
                <div class="tc-menuint-3">
                  <li><a href="<?php echo get_term_link($cat2) ?>"><?php echo $cat2->name; ?></a></li>
                  <div class="tc-menuint-4"> <?php
                    foreach ($cats as $key => $cat3):
                      if ($cat3->parent == $cat2->term_id): ?>
                        <li><a href="<?php echo get_term_link($cat3) ?>"><?php echo $cat3->name; ?></a></li><?php
                      endif;
                    endforeach; ?>
                  </div>
                </div> <?php
              endif;
            endforeach; ?>
          </div>
        </div><?php
      endif;
    endforeach;
  }
}

Then from anywhere we can call the function.

<?php menu_categories(); ?> 

Well is that!!

To understand the php code, we are getting all the categories like so:

$cat_args = array( 'orderby' => 'name', 'order' => 'asc', 'hide_empty' => true);
$cats = get_terms( 'product_cat', $cat_args );
foreach ($cats as $key => $cat):
  echo '<a href="https://wordpress.stackexchange.com/questions/390440/.get_term_link($cat).">'.$cat->name.'</a><br>';
endforeach;

Once all the categories and subcategories are showing: we can filter it to show only the categories (top level):

$cat_args = array( 'orderby' => 'name', 'order' => 'asc', 'hide_empty' => true);
$cats = get_terms( 'product_cat', $cat_args );
foreach ($cats as $key => $cat):
  if ($cat->parent == 0):
    echo '<a href="https://wordpress.stackexchange.com/questions/390440/.get_term_link($cat).">'.$cat->name.'</a><br>';
  endif;
endforeach;

If we want the sub-categories we can filter them again:

$cat_args = array( 'orderby' => 'name', 'order' => 'asc', 'hide_empty' => true);
$cats = get_terms( 'product_cat', $cat_args );
foreach ($cats as $key => $cat):
  if ($cat->parent == 0):
    echo '<a href="https://wordpress.stackexchange.com/questions/390440/.get_term_link($cat).">'.$cat->name.'</a><br>';

    foreach ($cats as $key => $cat2):
      if ($cat2->parent == $cat->term_id):
        echo '<a href=".get_term_link($cat2)." style="color:red;">'.$cat2->name.'</a><br>';
      endif;
    endforeach;

  endif;
endforeach;

then if we want a sub-sub-categorie, we can add another block of code like the one before changing in this case $cat2 to for example $cat3, and compare it to the term_id of the parent $cat2. Now if for some reason we need more sub-categories we can go on and on…

$cat_args = array( 'orderby' => 'name', 'order' => 'asc', 'hide_empty' => true);
$cats = get_terms( 'product_cat', $cat_args );
foreach ($cats as $key => $cat):
  if ($cat->parent == 0):
    echo '<a href="https://wordpress.stackexchange.com/questions/390440/.get_term_link($cat).">'.$cat->name.'</a><br>';
    foreach ($cats as $key => $cat2):
      if ($cat2->parent == $cat->term_id):
        echo '<a href=".get_term_link($cat2)." style="color:red;">'.$cat2->name.'</a><br>';
        
        foreach ($cats as $key => $cat3):
          if ($cat3->parent == $cat2->term_id):
            echo '<a href=".get_term_link($cat3)." style="color:green;">'.$cat3->name.'</a><br>';
          endif;
        endforeach;

      endif;
    endforeach;
  endif;
endforeach;