Register JS for block on frontend only

If you’re using WordPress 5.8 (e.g. v5.8.3), then I’m afraid the answer to this:

I know that I can use is_admin() to check if it’s in the editor and
not load a js file but I’m trying to see how it can be done with
register_block_type().

.. is it can’t; not in WordPress 5.8.

More Details

Excerpt from https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#view-script: (* note the “Since” part that I highlighted)

View Script

  • Property: viewScript
  • Since: WordPress 5.9.0

1| { "viewScript": "file:./build/view.js" }

Block type frontend script definition. It will be enqueued only when
viewing the content on the front of the site.

So the viewScript property (in block.json/JS) or the view-script in PHP, didn’t work because the property/argument will only be supported in WordPress 5.9 ( props to https://jeremyfelt.com/2021/12/17/some-block-json-minutia/ ).

Alternate Solution

Apart from only registering the script handle if ( ! is_admin() ), you could also try these:

  1. Unregister the script right after you called register_block_type(). E.g.

    add_action( 'init', function () {
        register_block_type( __DIR__, /* block.json */
            array(
                'render_callback' => 'render_my_block',
                'script'          => 'my-custom-js',
            )
        );
    
        wp_deregister_script( 'my-custom-js' );
    } );
    
  2. And manually register the script using the wp_enqueue_scripts hook. E.g.

    add_action( 'wp_enqueue_scripts', function () {
        wp_register_script( 'my-custom-js', plugins_url( 'build/script.js', __FILE__ ) );
    }, 9 );
    

But make sure to use the proper script handle based on your block name. E.g. If the name is my-plugin/notice, then the handle would be my-plugin-notice-script, i.e. the / (slash) is replaced with - (dash), and then append a -script at the end.

Tried & tested working in WordPress v5.8.3.