Wordpress - How to add crossorigin and integrity to wp_register_style? (Font Awesome 5)

style_loader_tag
style_loader_tag is an official WordPress API, see the documentation: https://developer.wordpress.org/reference/hooks/style_loader_tag/

apply_filters( 'style_loader_tag', $html, $handle, $href, $media )
Filters the HTML link tag of an enqueued style.


First enqueue your stylesheet, see documentation: https://developer.wordpress.org/reference/functions/wp_enqueue_style/

wp_enqueue_style( 'font-awesome-5', 'https://use.fontawesome.com/releases/v5.5.0/css/all.css', array(), null );

The $handle is 'font-awesome-5'
I do null so that there is no version number. This way it will be cached.

Simple str_replace
A simple str_replace is enough to achieve what you want, see example below

function add_font_awesome_5_cdn_attributes( $html, $handle ) {
    if ( 'font-awesome-5' === $handle ) {
        return str_replace( "media='all'", "media='all' integrity='sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU' crossorigin='anonymous'", $html );
    }
    return $html;
}
add_filter( 'style_loader_tag', 'add_font_awesome_5_cdn_attributes', 10, 2 );


Add different atributes
Below an example to add different atributes to (multiple) different stylesheets

function add_style_attributes( $html, $handle ) {

    if ( 'font-awesome-5' === $handle ) {
        return str_replace( "media='all'", "media='all' integrity='sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU' crossorigin='anonymous'", $html );
    }

    if ( 'another-style' === $handle ) {
        return str_replace( "media='all'", "media='all' integrity='blajbsf' example", $html );
    }

    if ( 'bootstrap-css' === $handle ) {
        return str_replace( "media='all'", "media='all' integrity='something-different' crossorigin='anonymous'", $html );
    }

    return $html;
}
add_filter( 'style_loader_tag', 'add_style_attributes', 10, 2 );


Add attributes to all styles
Below an example to add the same atributes to more than one stylesheet

function add_attributes_to_all_styles( $html, $handle ) {

        // add style handles to the array below
        $styles = array(
            'font-awesome-5',
            'another-style',
            'bootstrap-css'
        );

        foreach ( $styles as $style ) {
            if ( $style === $handle ) {
                return str_replace( "media='all'", "media='all' integrity='sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU' crossorigin='anonymous'", $html );
            }
        }

        return $html;
}
add_filter( 'style_loader_tag', 'add_attributes_to_all_styles', 10, 2 );




script_loader_tag
I also would like to explain the script_loader_tag, because this is also handy, but this API works in combination with wp_enqueue_script.

The script_loader_tag API is almost the same, only some small differences, see documentation: https://developer.wordpress.org/reference/hooks/script_loader_tag/

apply_filters( 'script_loader_tag', $tag, $handle, $src )
Filters the HTML script tag of an enqueued script.


Below an example to defer a single script

function add_defer_jquery( $tag, $handle ) {
    if ( 'jquery' === $handle ) {
        return str_replace( "src", "defer src", $tag );
    }
    return $tag;
}
add_filter( 'script_loader_tag', 'add_defer_jquery', 10, 2 );


Below an example to defer more than one script

function add_defer_attribute( $tag, $handle ) {

    // add script handles to the array below
    $scripts_to_defer = array(
        'jquery',
        'jquery-migrate',
        'bootstrap-bundle-js'
    );

    foreach ( $scripts_to_defer as $defer_script ) {
        if ( $defer_script === $handle ) {
            return str_replace( "src", "defer src", $tag );
        }
    }

    return $tag;
}
add_filter( 'script_loader_tag', 'add_defer_attribute', 10, 2 );

So I have explained both API's style_loader_tag and script_loader_tag. And I gave some examples for both API's I hope that this is useful for a lot of people out there. I have experience with both API's.


UPDATE
@CKMacLeod Thank you for your update, this clarifies things. We're mostly on the same page. As I said, I'm a WordPress developer and if you want to publish a theme and/or plugin on https://wordpress.org you're essentially forced to abide by the "WordPress Coding Standards" or they will simply reject your theme and/or plugin.

That's why I encourage developers out there to use "the WordPress way". I understand that sometimes there are no differences whatsoever, but it's also convenience. As you said yourself you could download Font Awesome and include it in your theme and/or plugin, this way you would only need to remove the style_loader_tag function and modify your wp_enqueue_style function.

And one last thing, in the past (5 years ago) some caching, combining and minifying plugins didn't work and most of the times I would find out why those developers who made the theme simply put things in the head in the theme and/or echoed them. Most caching plugins, who also (most of the time) provide options to combine, minify and delay execution of scripts became smarter and better at detecting bad code and working around them. But this is not preferred. That's why I encourage people to code with standards/conventions in mind.

As a developer, you always need to take into consideration what people could do with your code and taking compatibility in mind. So not taking the easy solution but the best optimal solution. I hope I have clarified my viewpoint.

EDIT
@CKMacLeod Thank you for the (technical) debate, I hope that you realize how important this is (using WordPress API's in your own development). Again, I have been looking around and even now if I look at the FAQ's of most popular minify plugins I usually see this one way or the other, for example:

Question: Why are some of the CSS and JS files not being merged?
Answer: The plugin only processes JS and CSS files enqueued using the official WordPress API method – https://developer.wordpress.org/themes/basics/including-css-javascript/ -as well as files from the same domain (unless specified on the settings).

See FAQ: https://wordpress.org/plugins/fast-velocity-minify/