sveltejs / kit

web development, streamlined
https://kit.svelte.dev
MIT License
18.48k stars 1.89k forks source link

Variable within `<svelte:head>` `script` tag doesn't get recognized #8132

Closed smblee closed 1 year ago

smblee commented 1 year ago

Describe the bug

<script lang="ts">
const VAR = 'Hi';
</script>

<svelte:head>
        <script>
            console.log(VAR);
        </script>
</svelte:head>

This would output console.log(VAR); as a raw string. instead of

        <script>
            console.log('Hi');
        </script>

AST Output:

 {
start: 73
end: 97
type: "Text"
data: "\n\t\t\tconsole.log(Var);\n\t\t"
}

This use case comes up when installing Google Analytics with their default instruction, and you want to use a env var for the analytics id (code below)

        <script
            async
            src="https://www.googletagmanager.com/gtag/js?id={GOOGLE_ANALYTICS_MEASUREMENT_ID}"
        >
        </script>
        <script>
            window.dataLayer = window.dataLayer || [];

            function gtag() {
                dataLayer.push(arguments);
            }

            gtag('js', new Date());
            gtag('config', GOOGLE_ANALYTICS_MEASUREMENT_ID);
        </script>

Reproduction

https://svelte.dev/repl/a4d646c2b73b4bf28959310d7ed1c4bf?version=3.54.0

Logs

No response

System Info

System:
    OS: macOS 13.0.1
    CPU: (10) arm64 Apple M1 Pro
    Memory: 189.02 MB / 32.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 16.19.0 - ~/.volta/tools/image/node/16.19.0/bin/node
    Yarn: 1.22.19 - ~/.volta/tools/image/yarn/1.22.19/bin/yarn
    npm: 9.2.0 - ~/.volta/tools/image/npm/9.2.0/bin/npm
  Browsers:
    Chrome: 108.0.5359.98
    Firefox: 105.0.2
    Safari: 16.1
  npmPackages:
    @sveltejs/adapter-auto: 1.0.0-next.90 => 1.0.0-next.90
    @sveltejs/kit: 1.0.0-next.580 => 1.0.0-next.580
    svelte: 3.55.0 => 3.54.0
    vite: 4.0.1 => 4.0.1

Severity

annoyance

Additional Information

No response

Conduitry commented 1 year ago

This is the intended behavior. Top-level variables in the component's main <script> block do not define global variables - and when you inject a script via <svelte:head>, that script is seen as-is by the browser, and so tries to refer to a global variable. If you need to inject a literal script with <svelte:head>, then you need to make sure you are defining a global variable that it has access to, for example by doing window.Var = 'hi'.

smblee commented 1 year ago

@Conduitry Hmm i think it's a bit confusing then since

        <script
            async
            src="https://www.googletagmanager.com/gtag/js?id={GOOGLE_ANALYTICS_MEASUREMENT_ID}"
        >
        </script>

This actually gets injected correctly with the variable to src="https://www.googletagmanager.com/gtag/js?id=Hi"

I get that this would work since it's part of the src tag instead of within the script tag, but syntactically they look like they should work. Maybe putting a compiler error/warning would be good esp since this is the official implementation guide for GA, and also by the top google search results for sveltekit add google analytics