1
0
mirror of synced 2025-12-22 19:34:15 -05:00

Add new fields to analytics event context: status, page_type, page_document_type (#21115)

* Add new fields to analytics event context: status, page-type, page-document-type

* Update schema-event.js

* Typescript

* Add status meta to error pages

* Update DefaultLayout.tsx

* Update DefaultLayout.tsx

* Update building-and-testing-nodejs-or-python.tsx
This commit is contained in:
Kevin Heis
2021-08-26 14:58:45 -07:00
committed by GitHub
parent 5cf83e524d
commit 4d0e9c70a3
12 changed files with 55 additions and 30 deletions

View File

@@ -11,7 +11,7 @@ import { useTranslation } from './hooks/useTranslation'
type Props = { children?: React.ReactNode }
export const DefaultLayout = (props: Props) => {
const { page, error, isHomepageVersion, currentPathWithoutLanguage, fullUrl } = useMainContext()
const { page, error, isHomepageVersion, currentPathWithoutLanguage, fullUrl, status } = useMainContext()
const { t } = useTranslation('errors')
return (
<div className="d-lg-flex">
@@ -26,6 +26,7 @@ export const DefaultLayout = (props: Props) => {
{/* For Google and Bots */}
{page.introPlainText && <meta name="description" content={page.introPlainText} />}
{/* For local site search indexing */}
{page.topics.length > 0 && <meta name="keywords" content={page.topics.join(',')} />}
{page.hidden && <meta name="robots" content="noindex" />}
@@ -41,6 +42,11 @@ export const DefaultLayout = (props: Props) => {
)
})}
{/* For analytics events */}
{status && <meta name="status" content={status.toString()} />}
{page.type && <meta name="page-type" content={page.type} />}
{page.documentType && <meta name="page-document-type" content={page.documentType} />}
{page.fullTitle && (
<>
<meta property="og:site_name" content="GitHub Docs" />

View File

@@ -12,6 +12,7 @@ export function GenericError() {
<div className="min-h-screen d-flex flex-column">
<Head>
<title>GitHub Documentation</title>
<meta name="status" content="500" />
</Head>
<SimpleHeader />

View File

@@ -84,6 +84,7 @@ export type MainContextT = {
featureFlags: FeatureFlags
page: {
documentType: string
type?: string
languageVariants: Array<{ name: string; code: string; hreflang: string; href: string }>
topics: Array<string>
title: string
@@ -104,10 +105,12 @@ export type MainContextT = {
searchVersions: Record<string, string>
nonEnterpriseDefaultVersion: string
status: number
fullUrl: string
}
export const getMainContextFromRequest = (req: any): MainContextT => {
export const getMainContext = (req: any, res: any): MainContextT => {
return {
breadcrumbs: req.context.breadcrumbs || {},
activeProducts: req.context.activeProducts,
@@ -134,6 +137,7 @@ export const getMainContextFromRequest = (req: any): MainContextT => {
page: {
languageVariants: req.context.page.languageVariants,
documentType: req.context.page.documentType,
type: req.context.page.type || null,
title: req.context.page.title,
fullTitle: req.context.page.fullTitle,
topics: req.context.page.topics || [],
@@ -166,6 +170,7 @@ export const getMainContextFromRequest = (req: any): MainContextT => {
featureFlags: {},
searchVersions: req.context.searchVersions,
nonEnterpriseDefaultVersion: req.context.nonEnterpriseDefaultVersion,
status: res.statusCode,
fullUrl: req.protocol + '://' + req.get('host') + req.originalUrl,
}
}

View File

@@ -65,6 +65,11 @@ type SendEventProps = {
preference_value?: string
}
function getMetaContent(name: string) {
const metaTag = document.querySelector(`meta[name="${name}"]`) as HTMLMetaElement
return metaTag?.content
}
export function sendEvent({ type, version = '1.0.0', ...props }: SendEventProps) {
let site_language = location.pathname.split('/')[1]
if (location.pathname.startsWith('/playground')) {
@@ -91,6 +96,9 @@ export function sendEvent({ type, version = '1.0.0', ...props }: SendEventProps)
search: location.search,
href: location.href,
site_language,
page_document_type: getMetaContent('page-document-type'),
page_type: getMetaContent('page-type'),
status: Number(getMetaContent('status') || 0),
// Device information
// os, os_version, browser, browser_version:

View File

@@ -63,6 +63,22 @@ const context = {
description: 'The language the user is viewing.',
enum: Object.keys(languages),
},
page_document_type: {
type: 'string',
description: 'The generic page document type based on URL path.',
enum: ['homepage', 'early-access', 'product', 'category', 'mapTopic', 'article'], // get-document-type.js
},
page_type: {
type: 'string',
description: 'Optional page type from the content frontmatter.',
enum: ['overview', 'quick_start', 'tutorial', 'how_to', 'reference'], // frontmatter.js
},
status: {
type: 'number',
description: 'The HTTP response status code of the main page HTML.',
minimum: 0,
maximum: 999,
},
// Device information
os: {

View File

@@ -16,8 +16,7 @@ router.post('/', async function postEvents(req, res, next) {
const fields = omit(req.body, '_csrf')
if (!ajv.validate(schema, fields)) {
if (isDev) console.log(ajv.errorsText())
return res.status(400).json({})
return res.status(400).json(isDev ? ajv.errorsText() : {})
}
if (req.hydro.maySend()) {

View File

@@ -9,6 +9,7 @@ const Custom404 = () => {
<div className="min-h-screen d-flex flex-column">
<Head>
<title>404 - Page not found</title>
<meta name="status" content="404" />
</Head>
<SimpleHeader />

View File

@@ -8,11 +8,7 @@ import displayToolSpecificContent from 'components/lib/display-tool-specific-con
import localization from 'components/lib/localization'
import wrapCodeTerms from 'components/lib/wrap-code-terms'
import {
MainContextT,
MainContext,
getMainContextFromRequest,
} from 'components/context/MainContext'
import { MainContextT, MainContext, getMainContext } from 'components/context/MainContext'
import {
getProductLandingContextFromRequest,
@@ -100,10 +96,11 @@ export default GlobalPage
export const getServerSideProps: GetServerSideProps<Props> = async (context) => {
const req = context.req as any
const res = context.res as any
return {
props: {
mainContext: getMainContextFromRequest(req),
mainContext: getMainContext(req, res),
productLandingContext: getProductLandingContextFromRequest(req),
productSubLandingContext: getProductSubLandingContextFromRequest(req),
tocLandingContext: getTocLandingContextFromRequest(req),

View File

@@ -1,11 +1,7 @@
import { GetServerSideProps } from 'next'
import { BeakerIcon, ZapIcon } from '@primer/octicons-react'
import {
MainContextT,
MainContext,
getMainContextFromRequest,
} from 'components/context/MainContext'
import { MainContextT, MainContext, getMainContext } from 'components/context/MainContext'
import {
PlaygroundContextProvider,
@@ -88,10 +84,11 @@ function PageInner() {
export const getServerSideProps: GetServerSideProps<Props> = async (context) => {
const req = context.req as any
const res = context.res as any
return {
props: {
mainContext: getMainContextFromRequest(req),
mainContext: getMainContext(req, res),
},
}
}

View File

@@ -1,10 +1,6 @@
import { GetServerSideProps } from 'next'
import { Liquid } from 'liquidjs'
import {
MainContextT,
MainContext,
getMainContextFromRequest,
} from 'components/context/MainContext'
import { MainContextT, MainContext, getMainContext } from 'components/context/MainContext'
import { DefaultLayout } from 'components/DefaultLayout'
import { GHAEReleaseNotes } from 'components/release-notes/GHAEReleaseNotes'
import { GHESReleaseNotes } from 'components/release-notes/GHESReleaseNotes'
@@ -40,11 +36,12 @@ export default function ReleaseNotes({
export const getServerSideProps: GetServerSideProps<Props> = async (context) => {
const req = context.req as any
const res = context.res as any
const currentVersion = req.context.allVersions[req.context.currentVersion]
const { latestPatch = '', latestRelease = '' } = req.context
return {
props: {
mainContext: getMainContextFromRequest(req),
mainContext: getMainContext(req, res),
currentVersion,
ghesContext: {
currentVersion,

View File

@@ -1,10 +1,6 @@
import { GetServerSideProps } from 'next'
import {
MainContextT,
MainContext,
getMainContextFromRequest,
} from 'components/context/MainContext'
import { MainContextT, MainContext, getMainContext } from 'components/context/MainContext'
import { Breadcrumbs } from 'components/Breadcrumbs'
import { DefaultLayout } from 'components/DefaultLayout'
import { useEffect, useRef } from 'react'
@@ -55,10 +51,11 @@ export default function GQLExplorer({ mainContext, graphqlExplorerUrl }: Props)
export const getServerSideProps: GetServerSideProps<Props> = async (context) => {
const req = context.req as any
const res = context.res as any
return {
props: {
mainContext: getMainContextFromRequest(req),
mainContext: getMainContext(req, res),
graphqlExplorerUrl: req.context.graphql.explorerUrl,
},
}

View File

@@ -3,7 +3,7 @@ import { GetServerSideProps } from 'next'
import {
MainContextT,
MainContext,
getMainContextFromRequest,
getMainContext,
useMainContext,
} from 'components/context/MainContext'
@@ -134,10 +134,11 @@ function LandingPage(props: LandingPageProps) {
export const getServerSideProps: GetServerSideProps<Props> = async (context) => {
const req = context.req as any
const res = context.res as any
return {
props: {
mainContext: getMainContextFromRequest(req),
mainContext: getMainContext(req, res),
gettingStartedLinks: req.context.featuredLinks.gettingStarted.map(
({ title, href, intro }: any) => ({ title, href, intro })
),