diff --git a/ghost/core/core/frontend/helpers/ghost_head.js b/ghost/core/core/frontend/helpers/ghost_head.js
index 09904905ce..9661145e09 100644
--- a/ghost/core/core/frontend/helpers/ghost_head.js
+++ b/ghost/core/core/frontend/helpers/ghost_head.js
@@ -141,6 +141,21 @@ function getWebmentionDiscoveryLink() {
}
}
+function getTinybirdTrackerScript(dataRoot) {
+ const scriptUrl = config.get('tinybird:tracker:scriptUrl');
+ const endpoint = config.get('tinybird:tracker:endpoint');
+ const token = config.get('tinybird:tracker:token');
+
+ const tbParams = _.map({
+ site_uuid: config.get('tinybird:tracker:id'),
+ post_uuid: dataRoot.post?.uuid,
+ member_uuid: dataRoot.member?.uuid,
+ member_status: dataRoot.member?.status
+ }, (value, key) => `tb_${key}="${value}"`).join(' ');
+
+ return ``;
+}
+
/**
* **NOTE**
* Express adds `_locals`, see https://github.com/expressjs/express/blob/4.15.4/lib/response.js#L962.
@@ -319,6 +334,10 @@ module.exports = async function ghost_head(options) { // eslint-disable-line cam
if (!_.isEmpty(tagCodeInjection)) {
head.push(tagCodeInjection);
}
+
+ if (config.get('tinybird') && config.get('tinybird:tracker') && config.get('tinybird:tracker:scriptUrl')) {
+ head.push(getTinybirdTrackerScript(dataRoot));
+ }
}
debug('end');
diff --git a/ghost/core/test/unit/frontend/helpers/__snapshots__/ghost_head.test.js.snap b/ghost/core/test/unit/frontend/helpers/__snapshots__/ghost_head.test.js.snap
index d38ac6af6e..b9bd03697e 100644
--- a/ghost/core/test/unit/frontend/helpers/__snapshots__/ghost_head.test.js.snap
+++ b/ghost/core/test/unit/frontend/helpers/__snapshots__/ghost_head.test.js.snap
@@ -457,7 +457,7 @@ Object {
"string": "
-
+
@@ -469,7 +469,7 @@ Object {
-
+
",
}
`;
@@ -959,6 +959,248 @@ Object {
}
`;
+exports[`{{ghost_head}} helper includes tinybird tracker script when config is set Sets tb_post_uuid on post page 1 1`] = `
+Object {
+ "rendered": "
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ",
+}
+`;
+
+exports[`{{ghost_head}} helper includes tinybird tracker script when config is set sets both tb_member_x variables and tb_post_uuid on logged in post page 1 1`] = `
+Object {
+ "rendered": "
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ",
+}
+`;
+
+exports[`{{ghost_head}} helper includes tinybird tracker script when config is set sets tb_member_x variables on logged in home page 1 1`] = `
+Object {
+ "rendered": "
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ",
+}
+`;
+
+exports[`{{ghost_head}} helper includes tinybird tracker script when config is set with all tb_variables set to undefined on logged out home page 1 1`] = `
+Object {
+ "rendered": "
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ",
+}
+`;
+
exports[`{{ghost_head}} helper members scripts includes portal when members enabled 1 1`] = `
Object {
"rendered": "
diff --git a/ghost/core/test/unit/frontend/helpers/ghost_head.test.js b/ghost/core/test/unit/frontend/helpers/ghost_head.test.js
index 2d07430fd7..2241abb0a9 100644
--- a/ghost/core/test/unit/frontend/helpers/ghost_head.test.js
+++ b/ghost/core/test/unit/frontend/helpers/ghost_head.test.js
@@ -340,6 +340,19 @@ describe('{{ghost_head}} helper', function () {
published_at: new Date(0),
updated_at: new Date(0)
}));
+
+ posts.push(createPost({ // Post 10
+ title: 'Testing stats',
+ uuid: 'post_uuid',
+ excerpt: 'Creating stats for the site',
+ mobiledoc: testUtils.DataGenerator.markdownToMobiledoc('Creating stats for the site'),
+ authors: [
+ authors[3]
+ ],
+ primary_author: authors[3],
+ published_at: new Date(0),
+ updated_at: new Date(0)
+ }));
};
before(function () {
@@ -1185,4 +1198,80 @@ describe('{{ghost_head}} helper', function () {
}));
});
});
+
+ describe('includes tinybird tracker script when config is set', function () {
+ beforeEach(function () {
+ configUtils.set({
+ tinybird: {
+ tracker: {
+ scriptUrl: 'https://unpkg.com/@tinybirdco/flock.js',
+ endpoint: 'https://api.tinybird.co',
+ token: 'tinybird_token',
+ id: 'tb_test_site_uuid'
+ }
+ }
+ });
+ });
+ it('with all tb_variables set to undefined on logged out home page', async function () {
+ await testGhostHead(testUtils.createHbsResponse({
+ locals: {
+ relativeUrl: '/',
+ context: ['home', 'index'],
+ safeVersion: '4.3'
+ }
+ }));
+ });
+
+ it('Sets tb_post_uuid on post page', async function () {
+ const renderObject = {
+ post: posts[10]
+ };
+
+ await testGhostHead(testUtils.createHbsResponse({
+ renderObject: renderObject,
+ locals: {
+ relativeUrl: '/post/',
+ context: ['post'],
+ safeVersion: '0.3'
+ }
+ }));
+ });
+
+ it('sets tb_member_x variables on logged in home page', async function () {
+ const renderObject = {
+ member: {
+ uuid: 'member_uuid',
+ status: 'paid'
+ }
+ };
+
+ await testGhostHead(testUtils.createHbsResponse({
+ renderObject: renderObject,
+ locals: {
+ relativeUrl: '/',
+ context: ['home', 'index'],
+ safeVersion: '4.3'
+ }
+ }));
+ });
+
+ it('sets both tb_member_x variables and tb_post_uuid on logged in post page', async function () {
+ const renderObject = {
+ member: {
+ uuid: 'member_uuid',
+ status: 'free'
+ },
+ post: posts[10]
+ };
+
+ await testGhostHead(testUtils.createHbsResponse({
+ renderObject: renderObject,
+ locals: {
+ relativeUrl: '/post/',
+ context: ['post'],
+ safeVersion: '4.3'
+ }
+ }));
+ });
+ });
});