fix utm unicode
This commit is contained in:
parent
654e8899a8
commit
d6ea5054c2
@ -30,14 +30,16 @@ export function AnalyticsScripts({ data, externalId }: AnalyticsScriptsProps) {
|
||||
const googleAnalyticsIds = data?.google_analytics || [];
|
||||
const yandexMetrikaIds = data?.yandex_metrica || [];
|
||||
|
||||
// Track which pixels have been initialized with external_id
|
||||
// Track which pixels have been initialized (basic init)
|
||||
const initializedPixelsRef = useRef<Set<string>>(new Set());
|
||||
// Track which pixels have been enhanced with external_id
|
||||
const enhancedPixelsRef = useRef<Set<string>>(new Set());
|
||||
|
||||
// Initialize FB Pixel when externalId becomes available
|
||||
// Initialize FB Pixel immediately when SDK is ready
|
||||
// external_id is OPTIONAL - we must not block tracking for users without fingerprint
|
||||
useEffect(() => {
|
||||
if (!externalId || facebookPixels.length === 0) return;
|
||||
if (facebookPixels.length === 0) return;
|
||||
|
||||
// Wait for fbq to be available
|
||||
const initPixels = () => {
|
||||
if (!window.fbq) {
|
||||
// SDK not loaded yet, retry in 100ms
|
||||
@ -48,20 +50,44 @@ export function AnalyticsScripts({ data, externalId }: AnalyticsScriptsProps) {
|
||||
facebookPixels.forEach((pixelId) => {
|
||||
if (initializedPixelsRef.current.has(pixelId)) return;
|
||||
|
||||
window.fbq!("init", pixelId, { external_id: externalId });
|
||||
// Initialize with external_id if available, otherwise without
|
||||
// This ensures ALL users get tracked, not just those with fingerprint
|
||||
if (externalId) {
|
||||
window.fbq!("init", pixelId, { external_id: externalId });
|
||||
enhancedPixelsRef.current.add(pixelId);
|
||||
} else {
|
||||
window.fbq!("init", pixelId);
|
||||
}
|
||||
|
||||
window.fbq!("track", "PageView");
|
||||
initializedPixelsRef.current.add(pixelId);
|
||||
});
|
||||
};
|
||||
|
||||
initPixels();
|
||||
}, [facebookPixels, externalId]);
|
||||
|
||||
// Enhance already-initialized pixels with external_id when it becomes available later
|
||||
// This improves matching for Conversions API deduplication
|
||||
useEffect(() => {
|
||||
if (!externalId || facebookPixels.length === 0) return;
|
||||
if (!window.fbq) return;
|
||||
|
||||
facebookPixels.forEach((pixelId) => {
|
||||
// Only enhance if pixel was initialized but not yet enhanced with external_id
|
||||
if (initializedPixelsRef.current.has(pixelId) && !enhancedPixelsRef.current.has(pixelId)) {
|
||||
// Re-init with external_id for better matching (doesn't fire PageView again)
|
||||
window.fbq!("init", pixelId, { external_id: externalId });
|
||||
enhancedPixelsRef.current.add(pixelId);
|
||||
}
|
||||
});
|
||||
}, [externalId, facebookPixels]);
|
||||
|
||||
if (!data) return null;
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Facebook Pixel SDK - loads immediately, init happens in useEffect when externalId ready */}
|
||||
{/* Facebook Pixel SDK - loads immediately, init happens in useEffect (with or without externalId) */}
|
||||
{facebookPixels.length > 0 && (
|
||||
<Script
|
||||
id="fb-pixel-sdk"
|
||||
|
||||
@ -65,17 +65,30 @@ export const getCurrentQueryParams = (): Record<string, string> => {
|
||||
return utmParams;
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert bytes to base64 string (handles UTF-8 properly)
|
||||
* MDN recommended approach: https://developer.mozilla.org/en-US/docs/Web/API/Window/btoa#unicode_strings
|
||||
*/
|
||||
const bytesToBase64 = (bytes: Uint8Array): string => {
|
||||
const binString = Array.from(bytes, (byte) =>
|
||||
String.fromCodePoint(byte)
|
||||
).join("");
|
||||
return btoa(binString);
|
||||
};
|
||||
|
||||
/**
|
||||
* Encode params as base64 JSON for state parameter
|
||||
* Uses URL-safe base64 encoding
|
||||
* Uses URL-safe base64 encoding with UTF-8 support
|
||||
* Handles Unicode characters (e.g., utm_campaign=夏セール)
|
||||
*/
|
||||
export const encodeStateParam = (params: Record<string, string>): string => {
|
||||
if (Object.keys(params).length === 0) return "";
|
||||
|
||||
try {
|
||||
const json = JSON.stringify(params);
|
||||
// Use btoa for base64, replace unsafe chars for URL
|
||||
const base64 = btoa(json)
|
||||
// Encode string as UTF-8 bytes, then convert to base64
|
||||
const bytes = new TextEncoder().encode(json);
|
||||
const base64 = bytesToBase64(bytes)
|
||||
.replace(/\+/g, "-")
|
||||
.replace(/\//g, "_")
|
||||
.replace(/=+$/, "");
|
||||
|
||||
Loading…
Reference in New Issue
Block a user