Using environment variables within script tags

2024-07-14

It is usually not considered an issue to have hard coded api keys that are meant to be exposed in the client side like in the case of analytics tools like Google and Posthog. However, I wanted my API keys for external services to be in an environment variable for better organization, as well as for the ability to quickly change them in the case that my key was taken and messed up my analytics.

If you follow the docs of setting up Posthog for Astro, you will find that they are suggesting you to copy and paste the script tag like this:

<!-- Won't work -->
<script is:inline>
    !function(t,e){var o,n,p,r;e.__SV...;
    posthog.init('your_project_api_key',{api_host:'https://us.i.posthog.com', person_profiles: 'identified_only' // or 'always' to create profiles for anonymous users as well
        })
</script>

If you wanted to use an env, you might try to import it the two code fences and reference it inside the script like:

<!-- Won't work -->
---
const API_KEY = import.meta.env.API_KEY
---
<script is:inline>
    !function(t,e){var o,n,p,r;e.__SV...;
    posthog.init(API_KEY,{api_host:'https://us.i.posthog.com', person_profiles: 'identified_only' // or 'always' to create profiles for anonymous users as well
        })
</script>

However, this won’t work because the script tag is not processed by Astro with the is:inline directive. You will need to use the define:vars directive in order to pass the environment variables to the script tag when you are building your project. The following Astro component should work:

<!-- Works! -->
---
const API_KEY = import.meta.env.API_KEY
---
<script is:inline define:vars={{API_KEY}}>
    !function(t,e){var o,n,p,r;e.__SV...;
    posthog.init(API_KEY,{api_host:'https://us.i.posthog.com', person_profiles: 'identified_only' // or 'always' to create profiles for anonymous users as well
        })
</script>