Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(gatsby-plugin-manifest): add option to generate apple-touch-icons links #7256

Merged
merged 14 commits into from
Nov 10, 2018
Merged
1 change: 1 addition & 0 deletions packages/gatsby-plugin-manifest/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
/gatsby-ssr.js
/gatsby-browser.js
/common.js
/components.js
/app-shell.js
56 changes: 28 additions & 28 deletions packages/gatsby-plugin-manifest/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ If you're using this plugin together with [`gatsby-plugin-offline`](https://www.
this plugin should be listed _before_ the offline plugin so that it can cache
the created manifest.webmanifest.

If you use the "automatic mode" (described below), this plugin will also add a favicon link to your html pages.
If you use the "automatic mode" or "hybrid mode" (described below), this plugin will also add a favicon link and "apple-touch-icon" links to your html pages.
moonmeister marked this conversation as resolved.
Show resolved Hide resolved

## Install

Expand Down Expand Up @@ -55,48 +55,48 @@ plugins: [

When in automatic mode the following json array is injected into the manifest configuration you provide and the icons are generated from it. The source icon you provide should be at least as big as the largest icon being generated.

```javascript
;[
```json
[
{
src: `icons/icon-48x48.png`,
sizes: `48x48`,
type: `image/png`,
"src": `icons/icon-48x48.png`,
"sizes": `48x48`,
"type": `image/png`
},
{
src: `icons/icon-72x72.png`,
sizes: `72x72`,
type: `image/png`,
"src": `icons/icon-72x72.png`,
"sizes": `72x72`,
"type": `image/png`
},
{
src: `icons/icon-96x96.png`,
sizes: `96x96`,
type: `image/png`,
"src": `icons/icon-96x96.png`,
"sizes": `96x96`,
"type": `image/png`
},
{
src: `icons/icon-144x144.png`,
sizes: `144x144`,
type: `image/png`,
"src": `icons/icon-144x144.png`,
"sizes": `144x144`,
"type": `image/png`
},
{
src: `icons/icon-192x192.png`,
sizes: `192x192`,
type: `image/png`,
"src": `icons/icon-192x192.png`,
"sizes": `192x192`,
"type": `image/png`
},
{
src: `icons/icon-256x256.png`,
sizes: `256x256`,
type: `image/png`,
"src": `icons/icon-256x256.png`,
"sizes": `256x256`,
"type": `image/png`
},
{
src: `icons/icon-384x384.png`,
sizes: `384x384`,
type: `image/png`,
"src": `icons/icon-384x384.png`,
"sizes": `384x384`,
"type": `image/png`
},
{
src: `icons/icon-512x512.png`,
sizes: `512x512`,
type: `image/png`,
},
"src": `icons/icon-512x512.png`,
"sizes": `512x512`,
"type": `image/png`
}
]
```

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`gatsby-plugin-manifest Adds "shortcut icon" and "manifest" links and "theme_color" meta tag to head 1`] = `
Array [
<link
href="/icons/icon-48x48.png"
rel="shortcut icon"
/>,
<link
href="/manifest.webmanifest"
rel="manifest"
/>,
<meta
content="#000000"
name="theme-color"
/>,
]
`;

exports[`gatsby-plugin-manifest Creates legacy apple touch links if opted in Using default set of icons 1`] = `
Array [
<link
href="/icons/icon-48x48.png"
rel="shortcut icon"
/>,
<link
href="/manifest.webmanifest"
rel="manifest"
/>,
<meta
content="#000000"
name="theme-color"
/>,
<link
href="/icons/icon-48x48.png"
rel="apple-touch-icon"
sizes="48x48"
/>,
<link
href="/icons/icon-72x72.png"
rel="apple-touch-icon"
sizes="72x72"
/>,
<link
href="/icons/icon-96x96.png"
rel="apple-touch-icon"
sizes="96x96"
/>,
<link
href="/icons/icon-144x144.png"
rel="apple-touch-icon"
sizes="144x144"
/>,
<link
href="/icons/icon-192x192.png"
rel="apple-touch-icon"
sizes="192x192"
/>,
<link
href="/icons/icon-256x256.png"
rel="apple-touch-icon"
sizes="256x256"
/>,
<link
href="/icons/icon-384x384.png"
rel="apple-touch-icon"
sizes="384x384"
/>,
<link
href="/icons/icon-512x512.png"
rel="apple-touch-icon"
sizes="512x512"
/>,
]
`;

exports[`gatsby-plugin-manifest Creates legacy apple touch links if opted in Using user specified list of icons 1`] = `
Array [
<link
href="/icons/icon-48x48.png"
rel="shortcut icon"
/>,
<link
href="/manifest.webmanifest"
rel="manifest"
/>,
<meta
content="#000000"
name="theme-color"
/>,
<link
href="/favicons/android-chrome-48x48.png"
rel="apple-touch-icon"
sizes="48x48"
/>,
<link
href="/favicons/android-chrome-512x512.png"
rel="apple-touch-icon"
sizes="512x512"
/>,
]
`;
71 changes: 71 additions & 0 deletions packages/gatsby-plugin-manifest/src/__tests__/gatsby-ssr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// const { shallow } = require(`enzyme`)
const { onRenderBody } = require(`../gatsby-ssr`)

let headComponents
const setHeadComponents = args => (headComponents = headComponents.concat(args))

const ssrArgs = {
setHeadComponents,
}

describe(`gatsby-plugin-manifest`, () => {
beforeEach(() => {
global.__PATH_PREFIX__ = ``
headComponents = []
})

it(`Adds "shortcut icon" and "manifest" links and "theme_color" meta tag to head`, () => {
onRenderBody(ssrArgs, { icon: true, theme_color: `#000000` })
expect(headComponents).toMatchSnapshot()
})

describe(`Creates legacy apple touch links if opted in`, () => {
it(`Using default set of icons`, () => {
onRenderBody(ssrArgs, {
icon: true,
theme_color: `#000000`,
legacyAppleTouchLinks: true,
})
expect(headComponents).toMatchSnapshot()
})

it(`Using user specified list of icons`, () => {
onRenderBody(ssrArgs, {
icon: true,
theme_color: `#000000`,
legacyAppleTouchLinks: true,
icons: [
{
src: `/favicons/android-chrome-48x48.png`,
sizes: `48x48`,
type: `image/png`,
},
{
src: `/favicons/android-chrome-512x512.png`,
sizes: `512x512`,
type: `image/png`,
},
],
})
expect(headComponents).toMatchSnapshot()
})
})

it(`Creates href attributes using pathPrefix`, () => {
global.__PATH_PREFIX__ = `/path-prefix`

onRenderBody(ssrArgs, {
icon: true,
theme_color: `#000000`,
legacyAppleTouchLinks: true,
})

headComponents
.filter(component => component.type === `link`)
.forEach(component => {
expect(component.props.href).toEqual(
expect.stringMatching(/^\/path-prefix\//)
)
})
})
})
5 changes: 2 additions & 3 deletions packages/gatsby-plugin-manifest/src/gatsby-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,11 @@ function generateIcons(icons, srcIcon) {

exports.onPostBootstrap = (args, pluginOptions) =>
new Promise((resolve, reject) => {
const { icon } = pluginOptions
const manifest = { ...pluginOptions }
const { icon, ...manifest } = pluginOptions

// Delete options we won't pass to the manifest.webmanifest.
delete manifest.plugins
moonmeister marked this conversation as resolved.
Show resolved Hide resolved
delete manifest.icon
delete manifest.legacyAppleTouchLinks

// If icons are not manually defined, use the default icon set.
if (!manifest.icons) {
Expand Down
39 changes: 26 additions & 13 deletions packages/gatsby-plugin-manifest/src/gatsby-ssr.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
import React from "react"
import { withPrefix } from "gatsby"
import { defaultIcons } from "./common.js"

exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => {
const icons = pluginOptions.icons || defaultIcons

// If icons were generated, also add a favicon link.
if (pluginOptions.icon) {
let favicon = `/icons/icon-48x48.png`
let favicon = icons && icons.length ? `/icons/icon-48x48.png` : null
moonmeister marked this conversation as resolved.
Show resolved Hide resolved

// The icon path could be different in hybrid mode
// this takes the first one of the possible icons
if (pluginOptions.icons && pluginOptions.icons.length) {
favicon = pluginOptions.icons[0].src
if (favicon) {
setHeadComponents([
<link
key={`gatsby-plugin-manifest-icon-link`}
rel="shortcut icon"
href={withPrefix(favicon)}
/>,
])
}

setHeadComponents([
<link
key={`gatsby-plugin-manifest-icon-link`}
rel="shortcut icon"
href={withPrefix(favicon)}
/>,
])
}

setHeadComponents([
<link
key={`gatsby-plugin-manifest-link`}
Expand All @@ -32,4 +32,17 @@ exports.onRenderBody = ({ setHeadComponents }, pluginOptions) => {
content={pluginOptions.theme_color}
/>,
])

if (pluginOptions.legacyAppleTouchLinks) {
setHeadComponents(
icons.map(icon => (
<link
key={`gatsby-plugin-manifest-apple-touch-icon-${icon.sizes}`}
rel="apple-touch-icon"
sizes={icon.sizes}
href={withPrefix(`${icon.src}`)}
/>
))
)
}
}