Skip to content

Commit

Permalink
fix(gatsby-plugin-typography): sort typography style tag first to avo…
Browse files Browse the repository at this point in the history
…id overwriting issues (#12295)

Fixes #12295
Fixes #6302
Fixes #9911
Fixes #1994
  • Loading branch information
KyleAMathews authored and DSchau committed Mar 5, 2019
1 parent 881ca39 commit 5caf95e
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 5 deletions.
103 changes: 103 additions & 0 deletions packages/gatsby-plugin-typography/src/__tests__/gatsby-ssr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
jest.mock(
`../.cache/typography`,
() => {
return {}
},
{ virtual: true }
)

import { onPreRenderHTML, onRenderBody } from "../gatsby-ssr"

const clone = arr => arr.reduce((merged, item) => merged.concat(item), [])

describe(`onRenderBody`, () => {
const setup = (options = {}, env = `build-html`) => {
process.env.BUILD_STAGE = env
const api = {
setHeadComponents: jest.fn(),
}
onRenderBody(api, options)
return api
}

afterAll(() => {
delete process.env.BUILD_STAGE
})

it(`invokes setHeadComponents with array of typography components`, () => {
const api = setup()

expect(api.setHeadComponents).toHaveBeenCalledWith([
expect.objectContaining({ key: `TypographyStyle` }),
expect.objectContaining({ key: `GoogleFont` }),
])
})

it(`only invokes setHeadComponents if BUILD_STAGE is build-html`, () => {
const api = setup({}, `develop`)

expect(api.setHeadComponents).not.toHaveBeenCalled()
})

it(`does not add google font if omitGoogleFont is passed`, () => {
const api = setup({
omitGoogleFont: true,
})

expect(api.setHeadComponents).toHaveBeenCalledWith([
expect.objectContaining({ key: `TypographyStyle` }),
])
})
})

describe(`onPreRenderHTML`, () => {
const setup = (components = []) => {
const api = {
getHeadComponents: jest.fn(() => components),
replaceHeadComponents: jest.fn(),
}
onPreRenderHTML(api)
return api
}

it(`reorders typography-js first`, () => {
const spies = setup([
{
key: `link-1234`,
},
{
key: `link-preload`,
},
{
key: `TypographyStyle`,
},
])

expect(spies.replaceHeadComponents).toHaveBeenCalledTimes(1)
expect(spies.replaceHeadComponents).toHaveBeenCalledWith(
expect.arrayContaining([
{
key: `TypographyStyle`,
},
])
)
})

it(`leaves non-typography head components as-is`, () => {
const components = [
{
key: `link-1234`,
},
{
key: `link-preload`,
},
{
key: `_____01234_____`,
},
]

const spies = setup(clone(components))

expect(spies.replaceHeadComponents).toHaveBeenCalledWith(components)
})
})
28 changes: 23 additions & 5 deletions packages/gatsby-plugin-typography/src/gatsby-ssr.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,33 @@ import { TypographyStyle, GoogleFont } from "react-typography"
import typography from "./.cache/typography"

exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => {
const googleFont = pluginOptions.omitGoogleFont ? (
[]
) : (
<GoogleFont key={`GoogleFont`} typography={typography} />
)
if (process.env.BUILD_STAGE === `build-html`) {
const googleFont = [].concat(
pluginOptions.omitGoogleFont ? (
[]
) : (
<GoogleFont key={`GoogleFont`} typography={typography} />
)
)
setHeadComponents([
<TypographyStyle key={`TypographyStyle`} typography={typography} />,
...googleFont,
])
}
}

// Move Typography.js styles to the top of the head section so they're loaded first
// and don't accidentally overwrite other styles. Typography.js is meant to
// be a configurable CSS reset so should always load first.
exports.onPreRenderHTML = ({ getHeadComponents, replaceHeadComponents }) => {

This comment has been minimized.

Copy link
@fullofcaffeine

fullofcaffeine Jan 30, 2020

I'm having an issue with this logic when using this plugin with bootstrap and gatsby-plugin-sass. Bootstrap rewrites the font rules from typography.js (_reboot.scss from bootstrap). I tried checking if it was possible to re-order the styles, but it's non-trivial, it seems. Is there a workaround for that?

const headComponents = getHeadComponents()
headComponents.sort((x, y) => {
if (x.key === `TypographyStyle`) {
return -1
} else if (y.key === `TypographyStyle`) {
return 1
}
return 0
})
replaceHeadComponents(headComponents)
}

0 comments on commit 5caf95e

Please sign in to comment.