Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Server Side Tagging Proxy - Safari Private Mode Fixing #152

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

### Added

- New Major Features:
- New SST script proxy to bypass request and avoid blocking on Safari Private Mode

## [3.5.4] - 2024-04-16

## [3.5.3] - 2024-03-26
Expand Down
10 changes: 10 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,16 @@ Check below the full list of tags and variables that are blocked, by default, in

Check out a list with all the GTM available tags on the [Google Developer Guide](https://developers.google.com/tag-manager/devguide).


### Google Server Side Tagging

It enables using and fixing the problems with Safari (private mode) tracking by creating a proxy to bypass the requests and send it to Google properly.

1) You must follow the steps to create the SST by following the documentation: [Server Side Tagging Fundamentals](https://developers.google.com/tag-platform/learn/sst-fundamentals)
2) Once you have configured that, you must enable the flag **Is Server side Tagging?** accessing the App Management and open the VTEX Google Tag Manager Settings

<!--- image reference here-->
![alt text](files/settings.png)
<!-- DOCS-IGNORE:start -->

## Contributors ✨
Expand Down
Binary file added docs/files/settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 14 additions & 5 deletions manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,25 @@
"support": {
"url": "https://support.vtex.com/hc/requests"
},
"availableCountries": [
"*"
]
"availableCountries": ["*"]
},
"builders": {
"react": "3.x",
"store": "0.x",
"pixel": "0.x",
"docs": "0.x"
"docs": "0.x",
"node": "7.x"
},
"dependencies": {
"vtex.pixel-interfaces": "1.x"
},
"policies": [
{
"name": "pixel"
"name": "outbound-access",
"attrs": {
"host": "www.googletagmanager.com",
"path": "/*"
}
}
],
"settingsSchema": {
Expand All @@ -50,6 +53,12 @@
"title": "Send Google Analytics 4 Events",
"description": "When this setting is active, also send the GA4 version of the events",
"type": "boolean"
},
"isServerSideTagging": {
"title": "Is Server side Tagging?",
"description": "When this setting is active, the GTM script will under the domain of the store",
"type": "boolean",
"default": false
}
}
},
Expand Down
5 changes: 5 additions & 0 deletions node/.vtexignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules/
.editorconfig
.eslintrc
.gitignore
README.md
30 changes: 30 additions & 0 deletions node/clients/googlejs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { InstanceOptions, IOContext } from '@vtex/api'
import { ExternalClient } from '@vtex/api'

const GOOGLE_ROUTE = 'http://www.googletagmanager.com/'

export class GoogleTagManagerScripts extends ExternalClient {
constructor(ctx: IOContext, options?: InstanceOptions) {
super(GOOGLE_ROUTE, ctx, {
...options,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'X-Vtex-Use-Https': 'true',
...options?.headers,
},
})
}

public async getScript(scriptName: string, parameters: string) {
const data = await this.http.get(`/gtag/${scriptName}?${parameters}`)

return data
}

public async getMainScript(scriptName: string, parameters: string) {
const data = await this.http.get(`/${scriptName}?${parameters}`)

return data
}
}
10 changes: 10 additions & 0 deletions node/clients/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { IOClients } from '@vtex/api'

import { GoogleTagManagerScripts } from './googlejs'

// Extend the default IOClients implementation with our own custom clients.
export class Clients extends IOClients {
public get googleTagManagerScripts() {
return this.getOrSet('googleTagManagerScripts', GoogleTagManagerScripts)
}
}
36 changes: 36 additions & 0 deletions node/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { Cached, ClientsConfig, ServiceContext } from '@vtex/api'
import { LRUCache, method, Service } from '@vtex/api'

import { Clients } from './clients'
import { script } from './routes/script'

const TIMEOUT_MS = 4000
const defaultClientOptions = {
retries: 1,
timeout: TIMEOUT_MS,
}

const memoryCache = new LRUCache<string, Cached>({ max: 1000 })

declare global {
type Context = ServiceContext<Clients>
}

const clients: ClientsConfig<Clients> = {
implementation: Clients,
options: {
default: defaultClientOptions,
settings: {
memoryCache,
},
},
}

export default new Service({
clients,
routes: {
script: method({
GET: script,
}),
},
})
29 changes: 29 additions & 0 deletions node/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "vtex.google-tag-manager",
"version": "0.0.1",
"dependencies": {
"@vtex/api": "6.47.0",
"co-body": "^6.0.0"
},
"devDependencies": {
"@types/co-body": "0.0.3",
"@types/cookie": "^0.3.2",
"@types/node": "^20.0.0",
"@vtex/api": "6.47.0",
"@vtex/prettier-config": "^0.3.1",
"@vtex/tsconfig": "^0.5.6",
"tslint": "^5.12.0",
"tslint-config-prettier": "^1.18.0",
"tslint-config-vtex": "^2.1.0",
"typescript": "5.5.3",
"vtex.google-tag-manager": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.google-tag-manager@3.5.4/public/@types/vtex.google-tag-manager",
"vtex.pixel-interfaces": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.pixel-interfaces@1.1.1/public/_types/react"
},
"resolutions": {
"@types/express": "4.16.0",
"@types/express-serve-static-core": "4.16.0"
},
"scripts": {
"lint": "tsc --noEmit && tslint -c tslint.json './**/*.ts'"
}
}
40 changes: 40 additions & 0 deletions node/routes/script.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
export async function script(ctx: Context) {
const {
clients: { googleTagManagerScripts },
vtex: {
route: { params },
},
} = ctx

const { name } = params

if (!name) {
ctx.status = 404
ctx.body = 'Not found'

return
}

// converting query parameters to string
const paramsString = Object.keys(ctx.query)
.map((key) => `${key}=${ctx.query[key]}`)
.join('&')

let data = ''

if (name === 'gtm.js') {
data = await googleTagManagerScripts.getMainScript(
name.toString(),
paramsString
)
} else {
data = await googleTagManagerScripts.getScript(
name.toString(),
paramsString
)
}

ctx.header['Content-Type'] = 'application/javascript'
ctx.header['Cache-Control'] = 'private, max-age=900'
ctx.body = data
}
14 changes: 14 additions & 0 deletions node/service.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"stack": "nodejs",
"memory": 512,
"ttl": 60,
"timeout": 3,
"minReplicas": 2,
"maxReplicas": 20,
"routes": {
"script": {
"path": "/_v/google-tag-manager/script/:name",
"public": true
}
}
}
11 changes: 11 additions & 0 deletions node/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "@vtex/tsconfig",
"compilerOptions": {
"noEmitOnError": false,
"lib": ["dom"],
"module": "esnext",
"moduleResolution": "node",
"target": "es2019"
},
"include": ["./typings/*.d.ts", "./**/*.tsx", "./**/*.ts"]
}
3 changes: 3 additions & 0 deletions node/tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "tslint-config-vtex"
}
Loading