@@ -6,21 +6,21 @@ import { defaultGroupLink, sidebarLinks } from '../docs/links';
66
77dotenv . config ( ) ;
88
9- const BASE = '/' ;
10- const BASE_WITH_ORIGIN = `https://developer.stackblitz.com${ BASE } ` ;
9+ const BASE_PATH = '/' ;
10+ const BASE_WITH_ORIGIN = `https://developer.stackblitz.com${ BASE_PATH } ` ;
1111
1212interface ThemeConfig extends DefaultTheme . Config {
1313 chatlio : {
14- id : string | undefined ,
15- allowedRoutes : ( RegExp | string ) [ ] ,
16- }
14+ id : string | undefined ;
15+ allowedRoutes : ( RegExp | string ) [ ] ;
16+ } ;
1717}
1818
1919export default defineConfigWithTheme < ThemeConfig > ( {
2020 srcDir : './docs' ,
21- outDir : `./build${ BASE } ` ,
21+ outDir : `./build${ BASE_PATH } ` ,
2222 assetsDir : 'assets' ,
23- base : BASE ,
23+ base : BASE_PATH ,
2424
2525 // Generate files as `/path/to/page.html` and URLs as `/path/to/page`
2626 cleanUrls : true ,
@@ -34,7 +34,7 @@ export default defineConfigWithTheme<ThemeConfig>({
3434 description :
3535 'Discover how to use StackBlitz, an online development environment for frontend, Node.js and the JavaScript ecosystem.' ,
3636 head : [
37- [ 'link' , { rel : 'icon' , type : 'image/png' , href : `${ BASE } img/theme/favicon.png` } ] ,
37+ [ 'link' , { rel : 'icon' , type : 'image/png' , href : `${ BASE_PATH } img/theme/favicon.png` } ] ,
3838 ...getAnalyticsTags ( process . env ) ,
3939 ] ,
4040
@@ -103,9 +103,9 @@ export default defineConfigWithTheme<ThemeConfig>({
103103 '/enterprise/' : sidebarLinks ( 'enterprise' , [ 'enterprise' ] ) ,
104104 } ,
105105 chatlio : {
106- allowedRoutes : [ `^${ BASE } teams/.*` , `^${ BASE } enterprise/.*` ] ,
106+ allowedRoutes : [ `^${ BASE_PATH } teams/.*` , `^${ BASE_PATH } enterprise/.*` ] ,
107107 id : process . env . VITE_CHATLIO_ID ,
108- }
108+ } ,
109109 } ,
110110
111111 postRender ( context ) {
@@ -122,31 +122,48 @@ export default defineConfigWithTheme<ThemeConfig>({
122122 template : {
123123 compilerOptions : {
124124 isCustomElement : ( tag ) => {
125- return [ " chatlio-widget" ] . includes ( tag . toLowerCase ( ) ) ;
126- }
127- }
128- }
125+ return [ ' chatlio-widget' ] . includes ( tag . toLowerCase ( ) ) ;
126+ } ,
127+ } ,
128+ } ,
129129 } ,
130130} ) ;
131131
132- function getAnalyticsTags ( env : NodeJS . ProcessEnv ) : HeadConfig [ ] {
133- if ( ! env . VITE_GTAG_ID ) {
134- return [ ] ;
132+ function getAnalyticsTags ( {
133+ VITE_GTM_ID = '' ,
134+ VITE_GTAG_ID = '' ,
135+ } : NodeJS . ProcessEnv ) : HeadConfig [ ] {
136+ // Fail the build if we have a defined but malformed analytics id
137+ const idPattern = / ^ ( G | G T M ) - [ A - Z \d ] + $ / ;
138+ for ( const [ name , value ] of Object . entries ( { VITE_GTM_ID , VITE_GTAG_ID } ) ) {
139+ if ( value && ! idPattern . test ( value ) ) {
140+ throw new Error ( `Invalid ${ name } value: '${ value } '` ) ;
141+ }
135142 }
136- return [
137- [
138- 'script' ,
139- { src : `https://www.googletagmanager.com/gtag/js?id=${ env . VITE_GTAG_ID } ` , async : '' } ,
140- ] ,
141- [
142- 'script' ,
143- { } ,
144- `function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag('js',new Date),gtag('config','${ env . VITE_GTAG_ID } ',{anonymize_ip:true})` ,
145- ] ,
146- ] ;
143+
144+ const tags : HeadConfig [ ] = [ ] ;
145+
146+ // We're migrating from gtag.js to gtm.js, but using both as we verify this change
147+ if ( VITE_GTM_ID ) {
148+ const js = `(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
149+ new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
150+ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
151+ 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
152+ })(window,document,'script','dataLayer','${ VITE_GTM_ID } ');` ;
153+ tags . push ( [ 'script' , { } , js ] ) ;
154+ }
155+
156+ if ( VITE_GTAG_ID ) {
157+ const url = `https://www.googletagmanager.com/gtag/js?id=${ VITE_GTAG_ID } ` ;
158+ tags . push ( [ 'script' , { async : '' , src : url } ] ) ;
159+ const source = `function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag('js',new Date),gtag('config','${ VITE_GTAG_ID } ',{anonymize_ip:true})` ;
160+ tags . push ( [ 'script' , { } , source ] ) ;
161+ }
162+
163+ return tags ;
147164}
148165
149- function getSearchConfig ( env : NodeJS . ProcessEnv ) {
166+ function getSearchConfig ( env : NodeJS . ProcessEnv ) : ThemeConfig [ 'search' ] {
150167 if ( env . VITE_ALGOLIA_ID && env . VITE_ALGOLIA_KEY ) {
151168 return {
152169 provider : 'algolia' ,
0 commit comments