Comments (13)
@maruthasalamr Unfortunately I'm a bit busy at the moment, but I'll try to look into it in the coming days.
from partytown.
The code snippet is hard to read, but I think you might indeed be missing a closing bracket in your dangerouslySetInnerHTML
:
dangerouslySetInnerHTML={{
__html:(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-XXXXXXXX')
}}
Notice the trailing bracket after 'GTM-XXXXXXXX'. It's missing in your code above and hence leading to the JavaScript error.
Again: GTM preview is not possible at the moment with Partytown. For more information refer to #72.
from partytown.
@j0Shi82 thanks now the error is gone but how to fix the CORS error
can please help on this ?
![image](https://private-user-images.githubusercontent.com/78694065/308528671-c2836e57-65e8-477b-94f7-701875b6bff9.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTk2ODE1NzgsIm5iZiI6MTcxOTY4MTI3OCwicGF0aCI6Ii83ODY5NDA2NS8zMDg1Mjg2NzEtYzI4MzZlNTctNjVlOC00NzdiLTk0ZjctNzAxODc1YjZiZmY5LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA2MjklMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNjI5VDE3MTQzOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTk2YmFlNzI4YjcwZjViYjRiZGU5ZTg3ZWQ0ZTgwOGE0ZWNiNzU3YzFkYmM3N2U0MmJkYmNhYTA3NmM1ZjA2NGYmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.KItjpX02ACdKOEVF6XVdfa7lIIVnR16hUH7OPRn__3w)
from partytown.
Sure. As mentioned in the docs, requests from within a Web Worker require the correct CORS headers. It's a security measure that all modern browsers implement.
Apparently, CookieBot does not serve their assets with CORS headers. What you can do is host the script yourself (I have no experience with Gatsby, but there surely is a public
folder you can work with). In case the script is dynamic and you have to get it from the vendor directly, you will need to set up a proxy as described here.
Cloudflare offers 100k requests for free (https://developers.cloudflare.com/workers/platform/pricing/), but you can obviously use whatever service you wish or deploy your own server that proxies the requests with the correct CORS header. The Cloudflare worker could look like this:
export default {
async fetch(request) {
// node_modules/itty-router/dist/itty-router.min.mjs
function e({ base: t = "", routes: n = [] } = {}) {
return { __proto__: new Proxy({}, { get: (e2, a, o) => (e3, ...r) => n.push([a.toUpperCase(), RegExp(`^${(t + e3).replace(/(\/?)\*/g, "($1.*)?").replace(/\/$/, "").replace(/:(\w+)(\?)?(\.)?/g, "$2(?<$1>[^/]+)$2$3").replace(/\.(?=[\w(])/, "\\.").replace(/\)\.\?\(([^\[]+)\[\^/g, "?)\\.?($1(?<=\\.)[^\\.")}/*$`), r]) && o }), routes: n, async handle(e2, ...r) {
let a, o, t2 = new URL(e2.url);
e2.query = Object.fromEntries(t2.searchParams);
for (var [p, s, u] of n)
if ((p === e2.method || "ALL" === p) && (o = t2.pathname.match(s))) {
e2.params = o.groups;
for (var c of u)
if (void 0 !== (a = await c(e2.proxy || e2, ...r)))
return a;
}
} };
}
var router = e();
router.get("/api/partytown/proxy", async (req) => {
let url = new URL(req.url);
if (!url.searchParams.has('url')) {
return new Response("Invalid", { status: 400 });
}
const decodedUrl = decodeURIComponent(url.searchParams.get('url'));
const res = await fetch(decodedUrl);
const newHeaders = new Headers(res.headers)
newHeaders.set('access-control-allow-origin', '*');
const newResponse = new Response(res.body, {
headers: newHeaders
})
return newResponse;
});
router.all("*", () => new Response("Not Found.", { status: 404 }));
return router.handle(request);
}
};
Then setup the resolveUrl
option in the Partytown config:
resolveUrl: (url, location, type) => {
if (type === 'script' && url.hostname.includes('cookiebot')) {
const proxyUrl = new URL('/api/partytown/proxy', YOUR_WORKER_DOMAIN);
proxyUrl.searchParams.append('url', url.href);
return proxyUrl;
}
}
You might need to adjust the snippet to fit your needs, but it should poke you into the right direction, I hope. Happy coding!
from partytown.
@j0Shi82 thank you for your quick response i have added the proxy in partytown config and I'm using AWS Cloudfront
distribution for my website hosting
Now the CORS error is fixed but 404 error comes. please help me on this
This is my Partytown gatsby configuration
<Partytown
key="partytown"
resolveUrl={(url, location, type) => {
let proxyUrl;
if (type === 'script' && url.hostname.includes('cookiebot')) {
proxyUrl = new URL('/api/partytown/proxy', 'http://localhost:9000/');
proxyUrl.searchParams.append('url', url.href);
return proxyUrl;
}
if (type === 'script' && url.hostname.includes('analytics')) {
proxyUrl = new URL('/api/partytown/proxy', 'http://localhost:9000/');
proxyUrl.searchParams.append('url', url.href);
return proxyUrl;
}
return url;
}}
debug={true}
forward={['dataLayer.push']}
/>,
<script
key="plugin-google-tagmanager"
type="text/partytown"
dangerouslySetInnerHTML={{
__html: `(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-MKPX3TV4');`,
}}
/>
This is error i got in network tab
![image](https://private-user-images.githubusercontent.com/78694065/308603140-8778d772-d407-42ce-a17f-2579cf3d68c4.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTk2ODE1NzgsIm5iZiI6MTcxOTY4MTI3OCwicGF0aCI6Ii83ODY5NDA2NS8zMDg2MDMxNDAtODc3OGQ3NzItZDQwNy00MmNlLWExN2YtMjU3OWNmM2Q2OGM0LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA2MjklMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNjI5VDE3MTQzOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTM5NjA4MGQ5Y2FmOTBkN2VhNDdhMTFjZGExNjc3YjcyYzE0Mzg1MTBhODg2N2IwOGJiOTQxNGI1NWJkZmUxYTkmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.F4rMzr25LKOW4L0_YQ_jlkA1AQYZkmmroHGGbZw5GSw)
![image](https://private-user-images.githubusercontent.com/78694065/308602850-3c16ea2d-d40e-4626-9c0b-2ec8ac3999fa.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTk2ODE1NzgsIm5iZiI6MTcxOTY4MTI3OCwicGF0aCI6Ii83ODY5NDA2NS8zMDg2MDI4NTAtM2MxNmVhMmQtZDQwZS00NjI2LTljMGItMmVjOGFjMzk5OWZhLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA2MjklMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNjI5VDE3MTQzOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTMwODY1NGNhYjE5M2RlNGIyZGFmNmRmY2MwNDcwNDIwNjZhY2EzMWQzZjFmNzlkZjY5NWY1YzgzOTAxNzNhOTkmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.gJG4b9HRtRmZqWpueidaevb5uyTw_r59SP1AQSqzjKQ)
from partytown.
@j0Shi82 can we do using cloudfront ?
Sure. As mentioned in the docs, requests from within a Web Worker require the correct CORS headers. It's a security measure that all modern browsers implement.
Apparently, CookieBot does not serve their assets with CORS headers. What you can do is host the script yourself (I have no experience with Gatsby, but there surely is a
public
folder you can work with). In case the script is dynamic and you have to get it from the vendor directly, you will need to set up a proxy as described here.Cloudflare offers 100k requests for free (https://developers.cloudflare.com/workers/platform/pricing/), but you can obviously use whatever service you wish or deploy your own server that proxies the requests with the correct CORS header. The Cloudflare worker could look like this:
export default { async fetch(request) { // node_modules/itty-router/dist/itty-router.min.mjs function e({ base: t = "", routes: n = [] } = {}) { return { __proto__: new Proxy({}, { get: (e2, a, o) => (e3, ...r) => n.push([a.toUpperCase(), RegExp(`^${(t + e3).replace(/(\/?)\*/g, "($1.*)?").replace(/\/$/, "").replace(/:(\w+)(\?)?(\.)?/g, "$2(?<$1>[^/]+)$2$3").replace(/\.(?=[\w(])/, "\\.").replace(/\)\.\?\(([^\[]+)\[\^/g, "?)\\.?($1(?<=\\.)[^\\.")}/*$`), r]) && o }), routes: n, async handle(e2, ...r) { let a, o, t2 = new URL(e2.url); e2.query = Object.fromEntries(t2.searchParams); for (var [p, s, u] of n) if ((p === e2.method || "ALL" === p) && (o = t2.pathname.match(s))) { e2.params = o.groups; for (var c of u) if (void 0 !== (a = await c(e2.proxy || e2, ...r))) return a; } } }; } var router = e(); router.get("/api/partytown/proxy", async (req) => { let url = new URL(req.url); if (!url.searchParams.has('url')) { return new Response("Invalid", { status: 400 }); } const decodedUrl = decodeURIComponent(url.searchParams.get('url')); const res = await fetch(decodedUrl); const newHeaders = new Headers(res.headers) newHeaders.set('access-control-allow-origin', '*'); const newResponse = new Response(res.body, { headers: newHeaders }) return newResponse; }); router.all("*", () => new Response("Not Found.", { status: 404 })); return router.handle(request); } };Then setup the
resolveUrl
option in the Partytown config:resolveUrl: (url, location, type) => { if (type === 'script' && url.hostname.includes('cookiebot')) { const proxyUrl = new URL('/api/partytown/proxy', YOUR_WORKER_DOMAIN); proxyUrl.searchParams.append('url', url.href); return proxyUrl; } }
You might need to adjust the snippet to fit your needs, but it should poke you into the right direction, I hope. Happy coding!
from partytown.
Cloudfront functions are JavaScript as well afaik. So you should be able to use the code snippet with small adjustments. A quick search revealed that Cloudfront functions may be limited to 1ms of CPU time. Not sure it's still up-to-date. But our production workers use 1.5ms of CPU time on average. So you might run a quota issue there.
Sorry I cannot assist more specifically. You will need to work with the Cloudfront docs to set up your proxy.
from partytown.
@j0Shi82 thank you for your response
CORS error is fixed and I have updated CORS in cloudfront behaviours.
Can we take it to production without the seeing the triggers/events are tracked in GTM preview mode ?
from partytown.
What you can do to verify that the data is flowing is go into your connected Analytics account, monitor the live view, and refresh your page a couple times. In case events appear there, you should be ok. I personally always set up GTM without Partytown to be able to use the debug mode and then move it into the worker. Usually it works fine, but you should absolutely keep an eye on your connected vendors to make sure the data is coming in as expected. Remember Partytown is an open source beta so you'll always need to do maintenance yourself. 👍
from partytown.
Yes, I can able to preview the tags in GTM without partytown and once i move the GTM into the worker i'm not able to preview the tags. Also i check the real time data in GA4 i can able to see the events appear there.
Thanks for your quick response
from partytown.
I'm using hubspot as tag which added in GTM so it is requesting for https://js.hs-analytics.net/analytics/1710241500000/000000.js but receiving 404 not found
This my proxy setup please help me on this
![image](https://private-user-images.githubusercontent.com/78694065/312052613-76fac178-86bd-4d47-89e1-465439706a3a.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTk2ODE1NzgsIm5iZiI6MTcxOTY4MTI3OCwicGF0aCI6Ii83ODY5NDA2NS8zMTIwNTI2MTMtNzZmYWMxNzgtODZiZC00ZDQ3LTg5ZTEtNDY1NDM5NzA2YTNhLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA2MjklMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNjI5VDE3MTQzOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTYwYWI5NzM1MmJkZjk3ZTM2OTc4MTc4ZTRhOWQ1ODRkZGIxYzE0MWVhNzgwMjhmOGE1OGVhNzY0NjU0ODU3YTQmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.KS1o4uoFQBOP3t6uHfRzXibq1ADina3l4-Jqez0wjps)
<Partytown
key="partytown"
resolveUrl={(url, location) => {
if (url.hostname.includes('analytics')) {
// Use a secure connection
if (url?.protocol === 'http:') {
url = new URL(url.href.replace('http', 'https'));
}
// Point to our proxied URL
const proxyUrl = new URL(location.origin + '/__third-party-proxy');
proxyUrl.searchParams.append('url', url.href);
return proxyUrl;
}
return url;
}}
debug={true}
forward={['dataLayer.push']}
/>
from partytown.
@j0Shi82
I have added the code in cloudfare worker and i have update config in partytown but still CORS issue occurs
can you please help on this ?
<Partytown
key="partytown"
resolveUrl={(url,type) => {
if (url?.protocol === 'http:') {
url = new URL(url.href.replace('http', 'https'))
}
if (type === 'script' && url.hostname.includes('analytics')) {
const proxyUrl = new URL('/api/partytown/proxy', 'https://reverse-proxy.maruthasalam-rajendran.workers.dev/');
proxyUrl.searchParams.append('url', url.href);
return proxyUrl;
}
return url;
}}
debug={true}
forward={['dataLayer.push']}
/>
![image](https://private-user-images.githubusercontent.com/78694065/312947740-01594485-b127-4bee-a935-e78f6d4259cf.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTk2ODE1NzgsIm5iZiI6MTcxOTY4MTI3OCwicGF0aCI6Ii83ODY5NDA2NS8zMTI5NDc3NDAtMDE1OTQ0ODUtYjEyNy00YmVlLWE5MzUtZTc4ZjZkNDI1OWNmLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA2MjklMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNjI5VDE3MTQzOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTBiYWE2MzQzMzUwYmQ1MGYxMmU2NGM4MzljNTk1YWZjYjc0NWJkMmY0ZGRkYjc3NTBlMzU0NmE0MWYzMGFiMTcmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.Z6mRrshbD4pUymmShlP3IpzYPFu4eMj96Rj_5s4LoS4)
![image](https://private-user-images.githubusercontent.com/78694065/312950166-bddec9f9-de3d-4dab-a545-df7a5a1b1159.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTk2ODE1NzgsIm5iZiI6MTcxOTY4MTI3OCwicGF0aCI6Ii83ODY5NDA2NS8zMTI5NTAxNjYtYmRkZWM5ZjktZGUzZC00ZGFiLWE1NDUtZGY3YTVhMWIxMTU5LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA2MjklMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNjI5VDE3MTQzOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTM5NDQ0NjdiMmRlODBlNDE5YjI5ZmE3Zjg1Y2JkZTJhNzc0MGQ4MmFkMWRiYTRlNDg1NTQ1OTJhNDMxY2Q0YWUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.GCKTM1qqXEkngSlJDBW2ig0-TPUbxnBugPM9O_bGhPg)
from partytown.
@j0Shi82 any update. It's look similar to resolveUrl
issue for Partytown
react component
#553
from partytown.
Related Issues (20)
- [📖] How can I load partytown from a pure HTML/JS website? HOT 1
- [🐞]404 errror throws while implementing partytown in gatsby application HOT 3
- Failed to register a ServiceWorker for scope ('https://example/~partytown/') with script ('https://example.com/~partytown/partytown-sw.js'): The script resource is behind a redirect, which is disallowed. HOT 1
- Partytown integration with Astro makes over 10'000 proxytown requests on page load[🐞] HOT 2
- [🐞] Google Tag Manager NextJS forward events coming as blank []
- [🐞] Cannot read property 'Error' of null
- [🐞] Proxy object could not be cloned HOT 1
- [🐞] Firefox: 404 partytown-sandbox-sw.html HOT 1
- [🐞] Firefox: Private Browsing for external Scripts HOT 1
- [🐞] GA4 sessions plummeted after migration of GTM to Partytown HOT 11
- [🐞] Objects and object properties can't be forwarded HOT 2
- [🐞]in statement is not reliable when running through partytown
- [📖] resolveSendBeaconRequestParameters missing in docs and React types HOT 1
- [🐞]: forwarding gtm dataLayer.push breaks immediate dataLayer pushes HOT 3
- [🐞] page_view and on_load events are not firing in GA4
- [🐞] Intercom does not work with party town
- [🐞]user_engagement is not working in GA4
- [🐞] AppsFlyer Smart Banner does not work
- [🐞] How to setup correctly partytown for astro.js
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from partytown.