6

When my Next JS app is compiled, it generates a list of script files to include like this.

<script src="/_next/static/chunks/main-1234.js" async=""></script>
<script src="/_next/static/chunks/webpack-1234.js" async=""></script>
<script src="/_next/static/chunks/framework.1234.js" async=""></script>
<script src="/_next/static/chunks/1234.5678.js" async=""></script>
<script src="/_next/static/chunks/commons.1234.js" async=""></script>
<script src="/_next/static/chunks/pages/_app-1234.js" async=""></script>
<script src="/_next/static/chunks/1234.5678.js" async=""></script>
<script src="/_next/static/chunks/pages/%5B%5B...path%5D%5D-1234.js" async=""></script>
<script src="/_next/static/1234/_buildManifest.js" async=""></script>
<script src="/_next/static/1234/_ssgManifest.js" async=""></script>

I want to add a custom data attribute to some of them like this.

<script data-cookieconsent="ignore" src="/_next/static/chunks/pages/%5B%5B...path%5D%5D-1234.js" async=""></script>

I've explored trying to do this in the next.config.js file as I know it's possible to make webpack overrides in there, but I'm not seeing a way to add data attributes to dynamically generated js files like this.

1 Answer 1

9

From Next.js 11

You'll need to extend and modify getScripts from the Head class in your _document.js file instead.

import Document, { Html, Head, Main, NextScript } from 'next/document'

class CustomHead extends Head {
    getScripts(files) {
        const originalScripts = super.getScripts(files);
        return originalScripts.map((script) => {
            return React.cloneElement(script, {
                'data-cookieconsent': this.props.cookieconsent
            });
        });
    }
}

class CustomDocument extends Document {
    render() {
        return (
            <Html>
                <CustomHead cookieconsent="ignore" />
                <body>
                    <Main />
                    <NextScript />
                </body>
            </Html>
        )
    }
}

export default CustomDocument

Before Next.js 11

An alternative solution is to extend the NextScript class in your _document.js file, as to include your custom data-* attribute in the scripts generated by Next.js.

import Document, { Html, Head, Main, NextScript } from 'next/document'

class CustomNextScript extends NextScript {
    getScripts(files) {
        const originalScripts = super.getScripts(files);
        return originalScripts.map((script) => {
            return React.cloneElement(script, {
                'data-cookieconsent': this.props.cookieconsent
            });
        });
    }
}

class CustomDocument extends Document {
    render() {
        return (
            <Html>
                <Head />
                <body>
                    <Main />
                    <CustomNextScript cookieconsent="ignore" />
                </body>
            </Html>
        )
    }
}

export default CustomDocument
Sign up to request clarification or add additional context in comments.

2 Comments

Smart solution. Thanks
This is perfect. I also had to do something similar for OneTrust blocking the app's own scripts with a data-ot-ignore attribute.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.