You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The PDF report is built with @react-pdf/renderer. Each section and widget styles its own text, links, buttons, badges, and cards from the raw Text, View, and Link primitives. The same styles and colors repeat across many files, so the report is hard to keep consistent, and each new widget repeats them.
Add a small set of shared PDF components that mirror the dashboard components. A text component mirrors Typography. Components for links, buttons, change badges, and chips mirror Link, Button, ChangeBadge, and Chip. Keep the report's colors and text styles in one theme.
Each section and widget then builds from these components, so the report stays consistent with the Figma design and a new widget reuses the components instead of repeating the styles.
Do not alter or remove anything below. The following sections will be managed by moderators only.
Acceptance criteria
Each repeated part of the report renders through one shared component:
A text component, similar to the dashboard Typography component, renders the report's text.
A link component, similar to the dashboard Link component, renders the report's links.
A button component, similar to the dashboard Button component, renders the report's buttons.
A change badge component, similar to the dashboard ChangeBadge component, renders the report's change badges.
A chip component, similar to the dashboard Chip component, renders the report's chips.
A card component renders the report's cards.
The PDF colors and text styles live in one place. Every component reads them from there, and no file holds a duplicate color or text-style value.
Every PDF section and widget builds from the shared components, and no section or widget keeps its own copy of a style the components provide.
A button like Button, with href, backgroundColor, labelColor, and children props.
Renders a <View> with the backgroundColor, borderRadius: 100, paddingVertical: 8, and paddingHorizontal: 16, wrapping a <Link src={ href }> with no underline. The link renders children as a PDFTypographylabelmedium with style={ { color: labelColor } }.
A change badge like ChangeBadge, with a change prop (the formatted string) and an isNegative prop.
Sets the background and text color from isNegative:
true: colors.negativeBadgeBackground with colors.negativeBadgeText.
false: colors.positiveBadgeBackground with colors.positiveBadgeText.
Renders a <View> with the background, borderRadius: 100, paddingVertical: 4, and paddingHorizontal: 8, wrapping change as a PDFTypographybodysmall in the text color.
Accepts style and children props, and renders the report's white cards.
Renders a <View> with style={ [ { backgroundColor: colors.surface, borderRadius: 16, padding: 24 }, style ] }.
Rename assets/js/components/pdf-export/shared-react-pdf-components/PDFHeaderSectionChip.tsx to PDFChip.tsx
Rename the component, its props interface, and its default export to PDFChip, like Chip, keeping the label and optional Icon props and no link target.
Renders a <View> with borderWidth: 1, borderColor: colors.border, borderRadius: 100, paddingVertical: 8, and paddingHorizontal: 12.
Renders the optional Icon at size 20 in colors.textPrimary with a 4 gap to the label, then the label as a PDFTypographylabelsmall with style={ { fontFamily: typographyFontFamilies.display, letterSpacing: 0.5 } }.
Render the area title with PDFTypographyheadlinemedium, and the "No report data available." and "Data unavailable." lines with PDFTypographybodysmall in colors.textMuted.
Read the page background from colors.pageBackground.
Remove the sectionTitle and emptyText rules from styles.
Render the "Your site's performance" line with PDFTypographybodymedium in colors.textMuted, and the date range with PDFTypographyheadlinesmall.
Render the site address with PDFLinkbodymedium in colors.textMuted when dashboardURL is set, and with PDFTypographybodymedium in colors.textMuted otherwise.
Render the "View dashboard in Site Kit" link with PDFLinklabelmedium and the chevron <Svg> as its trailingIcon, with the chevron fill reading colors.link.
Render the section chips with PDFChip, and read the divider color from colors.border.
Render the title with PDFTypographylabelmedium, and the two body lines with PDFTypographybodymedium, all in colors.noticeText.
Render the button with PDFButton, passing colors.noticeText as the background and colors.surface as the label color.
Read the card background from colors.noticeBackground, set the container borderRadius: 16 and paddingVertical: 14, and read the star icon fill from colors.noticeText.
Render the header cells with PDFTypographytitlesmall and the body cells with PDFTypographybodymedium, passing textAlign: 'right' through style for the right-aligned columns.
Read the row dividers from colors.border.
Remove the local headerTextStyles, bodyTextStyles, and COLORS.
PDFCard renders the colors.surface background with borderRadius: 16 and padding: 24, and merges the style prop.
Rename assets/js/components/pdf-export/shared-react-pdf-components/PDFHeaderSectionChip.test.tsx to PDFChip.test.tsx
Update it for PDFChip: the label rendered through PDFTypography in the display family at letter-spacing 0.5, the colors.border border, the size 20 icon, and no link target.
Cover the notice background, title, body, and button colors now read from colors.
Update assets/js/modules/analytics-4/components/dashboard/DashboardAllTrafficWidgetGA4/indexPDF.test.tsx, assets/js/modules/analytics-4/components/module/ModulePopularPagesWidgetGA4/ModulePopularPagesWidgetGA4PDF.test.tsx, and assets/js/modules/search-console/components/dashboard/SearchFunnelWidgetGA4/indexPDF.test.tsx
Update the empty-state assertions for the text now rendered in colors.textMuted through PDFTypography.
Update any remaining PDF component test that asserts a color or font value the shared components now own.
Feature Description
The PDF report is built with
@react-pdf/renderer. Each section and widget styles its own text, links, buttons, badges, and cards from the rawText,View, andLinkprimitives. The same styles and colors repeat across many files, so the report is hard to keep consistent, and each new widget repeats them.Add a small set of shared PDF components that mirror the dashboard components. A text component mirrors
Typography. Components for links, buttons, change badges, and chips mirrorLink,Button,ChangeBadge, andChip. Keep the report's colors and text styles in one theme.Each section and widget then builds from these components, so the report stays consistent with the Figma design and a new widget reuses the components instead of repeating the styles.
Do not alter or remove anything below. The following sections will be managed by moderators only.
Acceptance criteria
Typographycomponent, renders the report's text.Linkcomponent, renders the report's links.Buttoncomponent, renders the report's buttons.ChangeBadgecomponent, renders the report's change badges.Chipcomponent, renders the report's chips.Implementation Brief
Update
assets/js/components/pdf-export/pdf-theme.tsReplace the
PDF_COLOR_*constants,PDF_HEADER_COLORS, and the currentcolorsmap with onecolorsmap of the Figma report values:Replace
fontSizeswith atypographymap matching$typography-settings, keyed bytypethensize:fontSize,fontWeight,letterSpacing, andlineHeight.$fs-*,$ls-*, and$lh-*to a plain number, withfontWeight400or500.Add a
typographyFontFamiliesmap keyed bytype, matching$typography-font-families:Create
assets/js/components/pdf-export/shared-react-pdf-components/PDFTypography.tsxA text component like
Typography, withtype(default'body'),size(default'medium'), andstyleprops.Renders a
<Text>with:Create
assets/js/components/pdf-export/shared-react-pdf-components/PDFLink.tsxLink, withhref,type,size,trailingIcon, andstyleprops.<Link src={ href }>withflexDirection: 'row',alignItems: 'center', and no underline, wrapping the text and the optionaltrailingIcon.PDFTypographywith the giventypeandsizeandstyle={ [ { color: colors.link }, style ] }.Create
assets/js/components/pdf-export/shared-react-pdf-components/PDFButton.tsxButton, withhref,backgroundColor,labelColor, andchildrenprops.<View>with thebackgroundColor,borderRadius: 100,paddingVertical: 8, andpaddingHorizontal: 16, wrapping a<Link src={ href }>with no underline. The link renderschildrenas aPDFTypographylabelmediumwithstyle={ { color: labelColor } }.Create
assets/js/components/pdf-export/shared-react-pdf-components/PDFChangeBadge.tsxChangeBadge, with achangeprop (the formatted string) and anisNegativeprop.isNegative:true:colors.negativeBadgeBackgroundwithcolors.negativeBadgeText.false:colors.positiveBadgeBackgroundwithcolors.positiveBadgeText.<View>with the background,borderRadius: 100,paddingVertical: 4, andpaddingHorizontal: 8, wrappingchangeas aPDFTypographybodysmallin the text color.Create
assets/js/components/pdf-export/shared-react-pdf-components/PDFCard.tsxstyleandchildrenprops, and renders the report's white cards.<View>withstyle={ [ { backgroundColor: colors.surface, borderRadius: 16, padding: 24 }, style ] }.Rename
assets/js/components/pdf-export/shared-react-pdf-components/PDFHeaderSectionChip.tsxtoPDFChip.tsxPDFChip, likeChip, keeping thelabeland optionalIconprops and no link target.<View>withborderWidth: 1,borderColor: colors.border,borderRadius: 100,paddingVertical: 8, andpaddingHorizontal: 12.Iconat size20incolors.textPrimarywith a4gap to the label, then thelabelas aPDFTypographylabelsmallwithstyle={ { fontFamily: typographyFontFamilies.display, letterSpacing: 0.5 } }.Update
assets/js/components/pdf-export/section-icons.tsmakeIcon, read the default icon color fromcolors.textPrimaryin place ofPDF_HEADER_COLORS.chipIcon.Update
assets/js/components/pdf-export/shared-react-pdf-components/PDFWidgetSection.tsxPDFTypographybodylarge.PDFCard, passingcardStylethrough as itsstyle.marginBottom: 20onto the outer<View>.styles.Update
assets/js/components/pdf-export/shared-react-pdf-components/DashboardReport.tsxPDFTypographyheadlinemedium, and the "No report data available." and "Data unavailable." lines withPDFTypographybodysmallincolors.textMuted.colors.pageBackground.sectionTitleandemptyTextrules fromstyles.Update
assets/js/components/pdf-export/shared-react-pdf-components/PDFHeader.tsxPDFTypographybodymediumincolors.textMuted, and the date range withPDFTypographyheadlinesmall.PDFLinkbodymediumincolors.textMutedwhendashboardURLis set, and withPDFTypographybodymediumincolors.textMutedotherwise.PDFLinklabelmediumand the chevron<Svg>as itstrailingIcon, with the chevronfillreadingcolors.link.PDFChip, and read the divider color fromcolors.border.Update
assets/js/components/pdf-export/shared-react-pdf-components/PDFFooter.tsxPDFLinkbodysmallincolors.textMuted.linkstyle.Update
assets/js/components/pdf-export/shared-react-pdf-components/PDFSiteKitLogo.tsxPDFTypographyheadlinesmall, passing itsmarginLeft: 7throughstyle.Update
assets/js/components/pdf-export/shared-react-pdf-components/PDFEmailReportingNotice.tsxPDFTypographylabelmedium, and the two body lines withPDFTypographybodymedium, all incolors.noticeText.PDFButton, passingcolors.noticeTextas the background andcolors.surfaceas the label color.colors.noticeBackground, set the containerborderRadius: 16andpaddingVertical: 14, and read the star icon fill fromcolors.noticeText.COLORSand text styles.Update
assets/js/components/pdf-export/shared-react-pdf-components/PDFMetricTile.tsxPDFTypographytitlesmall, the value withheadlinemedium, and the change label withbodysmallincolors.textMuted.PDFChangeBadge, passingchangeandisNegative.COLORS, the text styles, and thechipandchipTextstyles.Update
assets/js/components/pdf-export/shared-react-pdf-components/PDFMetricChartTile.tsxPDFCard.PDFTypographytitlesmall, the value withheadlinemedium, and the legend and change labels withbodysmallincolors.textMuted.PDFChangeBadge, mappingchangeDirection === 'down'toisNegative.PDFTypographybodysmallincolors.textMutedoncolors.pageBackground.COLORS, thecardand text styles, and theChangeArrowcomponent.Update
assets/js/components/pdf-export/shared-react-pdf-components/PDFTable.tsxPDFTypographytitlesmalland the body cells withPDFTypographybodymedium, passingtextAlign: 'right'throughstylefor the right-aligned columns.colors.border.headerTextStyles,bodyTextStyles, andCOLORS.Update
assets/js/modules/analytics-4/components/dashboard/DashboardAllTrafficWidgetGA4/indexPDF.tsxPDFTypographybodysmallincolors.textMuted.noDatarule fromstyles.Update
assets/js/modules/analytics-4/components/module/ModulePopularPagesWidgetGA4/ModulePopularPagesWidgetGA4PDF.tsxPDFTypographybodymedium.PDFLinkbodymedium, and the page URL link withPDFLinkbodysmall.PDFTypographybodysmallincolors.textMuted.borderRadiusfrom the table'scardStyle.bodyTextStyles, therank,title,url, andnoDatastyles, andPAGE_LINK_COLOR.Update
assets/js/modules/search-console/components/dashboard/SearchFunnelWidgetGA4/indexPDF.tsxPDFTypographybodylarge.PDFTypographybodysmallincolors.textMuted.headingandnoDatatext rules fromstyles.Test Coverage
assets/js/components/pdf-export/shared-react-pdf-components/PDFTypography.test.tsxPDFMetricTile.test.tsxfor thereact-test-renderersetup:PDFTypographyrenders a<Text>with the font family, size, weight, line height, and letter spacing of the giventypeandsize.PDFTypographydefaults tobodymediumwhentypeandsizeare omitted.PDFTypographymerges thestyleprop over the token style.assets/js/components/pdf-export/shared-react-pdf-components/PDFLink.test.tsxPDFLinklinks tohrefwith no underline and the link color, renders thetrailingIconwhen one is given, and takes the color from thestyleprop.assets/js/components/pdf-export/shared-react-pdf-components/PDFButton.test.tsxPDFButtonrenders the link tohref, and reads the background and label color from its props.assets/js/components/pdf-export/shared-react-pdf-components/PDFChangeBadge.test.tsxPDFChangeBadgeuses the positive colors for a rising change and the negative colors for a falling change.assets/js/components/pdf-export/shared-react-pdf-components/PDFCard.test.tsxPDFCardrenders thecolors.surfacebackground withborderRadius: 16andpadding: 24, and merges thestyleprop.assets/js/components/pdf-export/shared-react-pdf-components/PDFHeaderSectionChip.test.tsxtoPDFChip.test.tsxPDFChip: the label rendered throughPDFTypographyin the display family at letter-spacing0.5, thecolors.borderborder, the size20icon, and no link target.assets/js/components/pdf-export/shared-react-pdf-components/PDFMetricChartTile.test.tsxassets/js/components/pdf-export/shared-react-pdf-components/PDFEmailReportingNotice.test.tsxcolors.assets/js/modules/analytics-4/components/dashboard/DashboardAllTrafficWidgetGA4/indexPDF.test.tsx,assets/js/modules/analytics-4/components/module/ModulePopularPagesWidgetGA4/ModulePopularPagesWidgetGA4PDF.test.tsx, andassets/js/modules/search-console/components/dashboard/SearchFunnelWidgetGA4/indexPDF.test.tsxcolors.textMutedthroughPDFTypography.QA Brief
Changelog entry