Added stats tracker script to ghost head (#20881)
closes https://linear.app/tryghost/issue/ANAL-9/initial-tracker-in-ghost-head - Given that all of the correct config is in place, output a tracking script - This allows us to send pageview events into tinybird - All of the details (location of the script, destination etc) are kept in config so that it's easy to change for different environments
This commit is contained in:
parent
d30164df97
commit
f79f5471b4
@ -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 `<script defer src="${scriptUrl}" data-host="${endpoint}" data-token="${token}" ${tbParams}></script>`;
|
||||
}
|
||||
|
||||
/**
|
||||
* **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');
|
||||
|
@ -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": "<link rel=\\"canonical\\" href=\\"http://127.0.0.1:2369/post/\\">
|
||||
<meta name=\\"referrer\\" content=\\"no-referrer-when-downgrade\\">
|
||||
<link rel=\\"amphtml\\" href=\\"http://127.0.0.1:2369/post/amp/\\">
|
||||
|
||||
<meta property=\\"og:site_name\\" content=\\"Ghost\\">
|
||||
<meta property=\\"og:type\\" content=\\"article\\">
|
||||
<meta property=\\"og:title\\" content=\\"Testing stats\\">
|
||||
<meta property=\\"og:description\\" content=\\"Creating stats for the site\\">
|
||||
<meta property=\\"og:url\\" content=\\"http://127.0.0.1:2369/post/\\">
|
||||
<meta property=\\"og:image\\" content=\\"http://127.0.0.1:2369/content/images/site-cover.png\\">
|
||||
<meta property=\\"article:published_time\\" content=\\"1970-01-01T00:00:00.000Z\\">
|
||||
<meta property=\\"article:modified_time\\" content=\\"1970-01-01T00:00:00.000Z\\">
|
||||
<meta property=\\"article:author\\" content=\\"https://www.facebook.com/testuser\\">
|
||||
<meta name=\\"twitter:card\\" content=\\"summary_large_image\\">
|
||||
<meta name=\\"twitter:title\\" content=\\"Testing stats\\">
|
||||
<meta name=\\"twitter:description\\" content=\\"Creating stats for the site\\">
|
||||
<meta name=\\"twitter:url\\" content=\\"http://127.0.0.1:2369/post/\\">
|
||||
<meta name=\\"twitter:image\\" content=\\"http://127.0.0.1:2369/content/images/site-cover.png\\">
|
||||
<meta name=\\"twitter:label1\\" content=\\"Written by\\">
|
||||
<meta name=\\"twitter:data1\\" content=\\"Author name\\">
|
||||
<meta name=\\"twitter:creator\\" content=\\"@testuser\\">
|
||||
|
||||
<script type=\\"application/ld+json\\">
|
||||
{
|
||||
\\"@context\\": \\"https://schema.org\\",
|
||||
\\"@type\\": \\"Article\\",
|
||||
\\"publisher\\": {
|
||||
\\"@type\\": \\"Organization\\",
|
||||
\\"name\\": \\"Ghost\\",
|
||||
\\"url\\": \\"http://127.0.0.1:2369/\\",
|
||||
\\"logo\\": {
|
||||
\\"@type\\": \\"ImageObject\\",
|
||||
\\"url\\": \\"http://127.0.0.1:2369/favicon.ico\\"
|
||||
}
|
||||
},
|
||||
\\"author\\": {
|
||||
\\"@type\\": \\"Person\\",
|
||||
\\"name\\": \\"Author name\\",
|
||||
\\"image\\": {
|
||||
\\"@type\\": \\"ImageObject\\",
|
||||
\\"url\\": \\"http://127.0.0.1:2369/content/images/test-author-image.png\\"
|
||||
},
|
||||
\\"url\\": \\"https://mysite.com/fakeauthor/\\",
|
||||
\\"sameAs\\": [
|
||||
\\"http://authorwebsite.com\\",
|
||||
\\"https://www.facebook.com/testuser\\",
|
||||
\\"https://twitter.com/testuser\\"
|
||||
]
|
||||
},
|
||||
\\"headline\\": \\"Testing stats\\",
|
||||
\\"url\\": \\"http://127.0.0.1:2369/post/\\",
|
||||
\\"datePublished\\": \\"1970-01-01T00:00:00.000Z\\",
|
||||
\\"dateModified\\": \\"1970-01-01T00:00:00.000Z\\",
|
||||
\\"description\\": \\"Creating stats for the site\\",
|
||||
\\"mainEntityOfPage\\": \\"http://127.0.0.1:2369/post/\\"
|
||||
}
|
||||
</script>
|
||||
|
||||
<meta name=\\"generator\\" content=\\"Ghost 0.3\\">
|
||||
<link rel=\\"alternate\\" type=\\"application/rss+xml\\" title=\\"Ghost\\" href=\\"http://localhost:65530/rss/\\">
|
||||
|
||||
<script defer src=\\"https://cdn.jsdelivr.net/ghost/sodo-search@~[[VERSION]]/umd/sodo-search.min.js\\" data-key=\\"xyz\\" data-styles=\\"https://cdn.jsdelivr.net/ghost/sodo-search@~[[VERSION]]/umd/main.css\\" data-sodo-search=\\"http://127.0.0.1:2369/\\" crossorigin=\\"anonymous\\"></script>
|
||||
|
||||
<link href=\\"http://127.0.0.1:2369/webmentions/receive/\\" rel=\\"webmention\\">
|
||||
<script defer src=\\"https://unpkg.com/@tinybirdco/flock.js\\" data-host=\\"https://api.tinybird.co\\" data-token=\\"tinybird_token\\" tb_site_uuid=\\"tb_test_site_uuid\\" tb_post_uuid=\\"post_uuid\\" tb_member_uuid=\\"undefined\\" tb_member_status=\\"undefined\\"></script>",
|
||||
}
|
||||
`;
|
||||
|
||||
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": "<link rel=\\"canonical\\" href=\\"http://127.0.0.1:2369/post/\\">
|
||||
<meta name=\\"referrer\\" content=\\"no-referrer-when-downgrade\\">
|
||||
<link rel=\\"amphtml\\" href=\\"http://127.0.0.1:2369/post/amp/\\">
|
||||
|
||||
<meta property=\\"og:site_name\\" content=\\"Ghost\\">
|
||||
<meta property=\\"og:type\\" content=\\"article\\">
|
||||
<meta property=\\"og:title\\" content=\\"Testing stats\\">
|
||||
<meta property=\\"og:description\\" content=\\"Creating stats for the site\\">
|
||||
<meta property=\\"og:url\\" content=\\"http://127.0.0.1:2369/post/\\">
|
||||
<meta property=\\"og:image\\" content=\\"http://127.0.0.1:2369/content/images/site-cover.png\\">
|
||||
<meta property=\\"article:published_time\\" content=\\"1970-01-01T00:00:00.000Z\\">
|
||||
<meta property=\\"article:modified_time\\" content=\\"1970-01-01T00:00:00.000Z\\">
|
||||
<meta property=\\"article:author\\" content=\\"https://www.facebook.com/testuser\\">
|
||||
<meta name=\\"twitter:card\\" content=\\"summary_large_image\\">
|
||||
<meta name=\\"twitter:title\\" content=\\"Testing stats\\">
|
||||
<meta name=\\"twitter:description\\" content=\\"Creating stats for the site\\">
|
||||
<meta name=\\"twitter:url\\" content=\\"http://127.0.0.1:2369/post/\\">
|
||||
<meta name=\\"twitter:image\\" content=\\"http://127.0.0.1:2369/content/images/site-cover.png\\">
|
||||
<meta name=\\"twitter:label1\\" content=\\"Written by\\">
|
||||
<meta name=\\"twitter:data1\\" content=\\"Author name\\">
|
||||
<meta name=\\"twitter:creator\\" content=\\"@testuser\\">
|
||||
|
||||
<script type=\\"application/ld+json\\">
|
||||
{
|
||||
\\"@context\\": \\"https://schema.org\\",
|
||||
\\"@type\\": \\"Article\\",
|
||||
\\"publisher\\": {
|
||||
\\"@type\\": \\"Organization\\",
|
||||
\\"name\\": \\"Ghost\\",
|
||||
\\"url\\": \\"http://127.0.0.1:2369/\\",
|
||||
\\"logo\\": {
|
||||
\\"@type\\": \\"ImageObject\\",
|
||||
\\"url\\": \\"http://127.0.0.1:2369/favicon.ico\\"
|
||||
}
|
||||
},
|
||||
\\"author\\": {
|
||||
\\"@type\\": \\"Person\\",
|
||||
\\"name\\": \\"Author name\\",
|
||||
\\"image\\": {
|
||||
\\"@type\\": \\"ImageObject\\",
|
||||
\\"url\\": \\"http://127.0.0.1:2369/content/images/test-author-image.png\\"
|
||||
},
|
||||
\\"url\\": \\"https://mysite.com/fakeauthor/\\",
|
||||
\\"sameAs\\": [
|
||||
\\"http://authorwebsite.com\\",
|
||||
\\"https://www.facebook.com/testuser\\",
|
||||
\\"https://twitter.com/testuser\\"
|
||||
]
|
||||
},
|
||||
\\"headline\\": \\"Testing stats\\",
|
||||
\\"url\\": \\"http://127.0.0.1:2369/post/\\",
|
||||
\\"datePublished\\": \\"1970-01-01T00:00:00.000Z\\",
|
||||
\\"dateModified\\": \\"1970-01-01T00:00:00.000Z\\",
|
||||
\\"description\\": \\"Creating stats for the site\\",
|
||||
\\"mainEntityOfPage\\": \\"http://127.0.0.1:2369/post/\\"
|
||||
}
|
||||
</script>
|
||||
|
||||
<meta name=\\"generator\\" content=\\"Ghost 4.3\\">
|
||||
<link rel=\\"alternate\\" type=\\"application/rss+xml\\" title=\\"Ghost\\" href=\\"http://localhost:65530/rss/\\">
|
||||
|
||||
<script defer src=\\"https://cdn.jsdelivr.net/ghost/sodo-search@~[[VERSION]]/umd/sodo-search.min.js\\" data-key=\\"xyz\\" data-styles=\\"https://cdn.jsdelivr.net/ghost/sodo-search@~[[VERSION]]/umd/main.css\\" data-sodo-search=\\"http://127.0.0.1:2369/\\" crossorigin=\\"anonymous\\"></script>
|
||||
|
||||
<link href=\\"http://127.0.0.1:2369/webmentions/receive/\\" rel=\\"webmention\\">
|
||||
<script defer src=\\"https://unpkg.com/@tinybirdco/flock.js\\" data-host=\\"https://api.tinybird.co\\" data-token=\\"tinybird_token\\" tb_site_uuid=\\"tb_test_site_uuid\\" tb_post_uuid=\\"post_uuid\\" tb_member_uuid=\\"member_uuid\\" tb_member_status=\\"free\\"></script>",
|
||||
}
|
||||
`;
|
||||
|
||||
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": "<meta name=\\"description\\" content=\\"site description\\">
|
||||
<link rel=\\"canonical\\" href=\\"http://127.0.0.1:2369/\\">
|
||||
<meta name=\\"referrer\\" content=\\"no-referrer-when-downgrade\\">
|
||||
|
||||
<meta property=\\"og:site_name\\" content=\\"Ghost\\">
|
||||
<meta property=\\"og:type\\" content=\\"website\\">
|
||||
<meta property=\\"og:title\\" content=\\"Ghost\\">
|
||||
<meta property=\\"og:description\\" content=\\"site description\\">
|
||||
<meta property=\\"og:url\\" content=\\"http://127.0.0.1:2369/\\">
|
||||
<meta property=\\"og:image\\" content=\\"http://127.0.0.1:2369/content/images/site-cover.png\\">
|
||||
<meta name=\\"twitter:card\\" content=\\"summary_large_image\\">
|
||||
<meta name=\\"twitter:title\\" content=\\"Ghost\\">
|
||||
<meta name=\\"twitter:description\\" content=\\"site description\\">
|
||||
<meta name=\\"twitter:url\\" content=\\"http://127.0.0.1:2369/\\">
|
||||
<meta name=\\"twitter:image\\" content=\\"http://127.0.0.1:2369/content/images/site-cover.png\\">
|
||||
|
||||
<script type=\\"application/ld+json\\">
|
||||
{
|
||||
\\"@context\\": \\"https://schema.org\\",
|
||||
\\"@type\\": \\"WebSite\\",
|
||||
\\"publisher\\": {
|
||||
\\"@type\\": \\"Organization\\",
|
||||
\\"name\\": \\"Ghost\\",
|
||||
\\"url\\": \\"http://127.0.0.1:2369/\\",
|
||||
\\"logo\\": {
|
||||
\\"@type\\": \\"ImageObject\\",
|
||||
\\"url\\": \\"http://127.0.0.1:2369/favicon.ico\\"
|
||||
}
|
||||
},
|
||||
\\"url\\": \\"http://127.0.0.1:2369/\\",
|
||||
\\"image\\": {
|
||||
\\"@type\\": \\"ImageObject\\",
|
||||
\\"url\\": \\"http://127.0.0.1:2369/content/images/site-cover.png\\"
|
||||
},
|
||||
\\"mainEntityOfPage\\": \\"http://127.0.0.1:2369/\\",
|
||||
\\"description\\": \\"site description\\"
|
||||
}
|
||||
</script>
|
||||
|
||||
<meta name=\\"generator\\" content=\\"Ghost 4.3\\">
|
||||
<link rel=\\"alternate\\" type=\\"application/rss+xml\\" title=\\"Ghost\\" href=\\"http://localhost:65530/rss/\\">
|
||||
|
||||
<script defer src=\\"https://cdn.jsdelivr.net/ghost/sodo-search@~[[VERSION]]/umd/sodo-search.min.js\\" data-key=\\"xyz\\" data-styles=\\"https://cdn.jsdelivr.net/ghost/sodo-search@~[[VERSION]]/umd/main.css\\" data-sodo-search=\\"http://127.0.0.1:2369/\\" crossorigin=\\"anonymous\\"></script>
|
||||
|
||||
<link href=\\"http://127.0.0.1:2369/webmentions/receive/\\" rel=\\"webmention\\">
|
||||
<script defer src=\\"https://unpkg.com/@tinybirdco/flock.js\\" data-host=\\"https://api.tinybird.co\\" data-token=\\"tinybird_token\\" tb_site_uuid=\\"tb_test_site_uuid\\" tb_post_uuid=\\"undefined\\" tb_member_uuid=\\"member_uuid\\" tb_member_status=\\"paid\\"></script>",
|
||||
}
|
||||
`;
|
||||
|
||||
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": "<meta name=\\"description\\" content=\\"site description\\">
|
||||
<link rel=\\"canonical\\" href=\\"http://127.0.0.1:2369/\\">
|
||||
<meta name=\\"referrer\\" content=\\"no-referrer-when-downgrade\\">
|
||||
|
||||
<meta property=\\"og:site_name\\" content=\\"Ghost\\">
|
||||
<meta property=\\"og:type\\" content=\\"website\\">
|
||||
<meta property=\\"og:title\\" content=\\"Ghost\\">
|
||||
<meta property=\\"og:description\\" content=\\"site description\\">
|
||||
<meta property=\\"og:url\\" content=\\"http://127.0.0.1:2369/\\">
|
||||
<meta property=\\"og:image\\" content=\\"http://127.0.0.1:2369/content/images/site-cover.png\\">
|
||||
<meta name=\\"twitter:card\\" content=\\"summary_large_image\\">
|
||||
<meta name=\\"twitter:title\\" content=\\"Ghost\\">
|
||||
<meta name=\\"twitter:description\\" content=\\"site description\\">
|
||||
<meta name=\\"twitter:url\\" content=\\"http://127.0.0.1:2369/\\">
|
||||
<meta name=\\"twitter:image\\" content=\\"http://127.0.0.1:2369/content/images/site-cover.png\\">
|
||||
|
||||
<script type=\\"application/ld+json\\">
|
||||
{
|
||||
\\"@context\\": \\"https://schema.org\\",
|
||||
\\"@type\\": \\"WebSite\\",
|
||||
\\"publisher\\": {
|
||||
\\"@type\\": \\"Organization\\",
|
||||
\\"name\\": \\"Ghost\\",
|
||||
\\"url\\": \\"http://127.0.0.1:2369/\\",
|
||||
\\"logo\\": {
|
||||
\\"@type\\": \\"ImageObject\\",
|
||||
\\"url\\": \\"http://127.0.0.1:2369/favicon.ico\\"
|
||||
}
|
||||
},
|
||||
\\"url\\": \\"http://127.0.0.1:2369/\\",
|
||||
\\"image\\": {
|
||||
\\"@type\\": \\"ImageObject\\",
|
||||
\\"url\\": \\"http://127.0.0.1:2369/content/images/site-cover.png\\"
|
||||
},
|
||||
\\"mainEntityOfPage\\": \\"http://127.0.0.1:2369/\\",
|
||||
\\"description\\": \\"site description\\"
|
||||
}
|
||||
</script>
|
||||
|
||||
<meta name=\\"generator\\" content=\\"Ghost 4.3\\">
|
||||
<link rel=\\"alternate\\" type=\\"application/rss+xml\\" title=\\"Ghost\\" href=\\"http://localhost:65530/rss/\\">
|
||||
|
||||
<script defer src=\\"https://cdn.jsdelivr.net/ghost/sodo-search@~[[VERSION]]/umd/sodo-search.min.js\\" data-key=\\"xyz\\" data-styles=\\"https://cdn.jsdelivr.net/ghost/sodo-search@~[[VERSION]]/umd/main.css\\" data-sodo-search=\\"http://127.0.0.1:2369/\\" crossorigin=\\"anonymous\\"></script>
|
||||
|
||||
<link href=\\"http://127.0.0.1:2369/webmentions/receive/\\" rel=\\"webmention\\">
|
||||
<script defer src=\\"https://unpkg.com/@tinybirdco/flock.js\\" data-host=\\"https://api.tinybird.co\\" data-token=\\"tinybird_token\\" tb_site_uuid=\\"tb_test_site_uuid\\" tb_post_uuid=\\"undefined\\" tb_member_uuid=\\"undefined\\" tb_member_status=\\"undefined\\"></script>",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`{{ghost_head}} helper members scripts includes portal when members enabled 1 1`] = `
|
||||
Object {
|
||||
"rendered": "<meta name=\\"description\\" content=\\"site description\\">
|
||||
|
@ -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'
|
||||
}
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user