diff --git a/README.md b/README.md
index be44cc739e7c9..79a55e0c5464a 100644
--- a/README.md
+++ b/README.md
@@ -336,6 +336,14 @@ exports.data = {
export default MyComponent ...
```
+You can also use a named export for the data object:
+
+```javascript
+export const data = {
+ title: 'This is a title',
+}
+```
+
### Structure of a Gatsby site
* `config.toml` - Core application configuration is stored here. Available via a `require`
or `import` of 'config'. Values:
diff --git a/lib/isomorphic/create-routes.js b/lib/isomorphic/create-routes.js
index 92747beffac6d..d9fc1cdedfd55 100644
--- a/lib/isomorphic/create-routes.js
+++ b/lib/isomorphic/create-routes.js
@@ -145,7 +145,7 @@ module.exports = (files, pagesReq) => {
handler = wrappers[page.file.ext]
page.data = pagesReq(`./${page.requirePath}`)
} else if (reactComponentFileTypes.indexOf(page.file.ext) !== -1) {
- handler = pagesReq(`./${page.requirePath}`)
+ handler = requireComponent(pagesReq(`./${page.requirePath}`))
page.data = page.data === undefined ? {} : page.data
}
diff --git a/lib/utils/build-page/load-frontmatter.js b/lib/utils/build-page/load-frontmatter.js
index 8f0dc47baaff9..226964a98bc0a 100644
--- a/lib/utils/build-page/load-frontmatter.js
+++ b/lib/utils/build-page/load-frontmatter.js
@@ -3,6 +3,7 @@ import fs from 'fs'
import path from 'path'
import frontMatter from 'front-matter'
import objectAssign from 'object-assign'
+import _ from 'lodash'
import htmlFrontMatter from 'html-frontmatter'
import * as babylon from 'babylon'
import traverse from 'babel-traverse'
@@ -81,6 +82,21 @@ export default function loadFrontmatter(pagePath: string): {} {
})
}
},
+ ExportNamedDeclaration: function ExportNamedDeclaration(astPath) {
+ const { declaration } = astPath.node
+ if (declaration && declaration.type === 'VariableDeclaration') {
+ const dataVariableDeclarator = _.find(
+ declaration.declarations,
+ d => d.id.name === 'data'
+ )
+
+ if (dataVariableDeclarator && dataVariableDeclarator.init) {
+ dataVariableDeclarator.init.properties.forEach(node => {
+ data[node.key.name] = parseData(node.value)
+ })
+ }
+ }
+ },
})
} catch (e) {
// Ignore errors — we print out parse errors for user elsewhere.
diff --git a/test/fixtures/javascript-pages-frontmatter/pages/array-literal-named-export.js b/test/fixtures/javascript-pages-frontmatter/pages/array-literal-named-export.js
new file mode 100644
index 0000000000000..2901f258167e4
--- /dev/null
+++ b/test/fixtures/javascript-pages-frontmatter/pages/array-literal-named-export.js
@@ -0,0 +1,13 @@
+/* eslint-disable react/display-name */
+import React from 'react'
+
+export const data = {
+ titles: ['My title', 'My other title'],
+}
+
+export default () => (
+
+
My title
+ My other title
+
+)
diff --git a/test/fixtures/javascript-pages-frontmatter/pages/object-literal-named-export.js b/test/fixtures/javascript-pages-frontmatter/pages/object-literal-named-export.js
new file mode 100644
index 0000000000000..1a0e27f0b707a
--- /dev/null
+++ b/test/fixtures/javascript-pages-frontmatter/pages/object-literal-named-export.js
@@ -0,0 +1,16 @@
+/* eslint-disable react/display-name */
+import React from 'react'
+
+export const data = {
+ titles: {
+ main: 'My title',
+ sub: 'My other title',
+ },
+}
+
+export default () => (
+
+
My title
+ My other title
+
+)
diff --git a/test/fixtures/javascript-pages-frontmatter/pages/string-literal-named-export.js b/test/fixtures/javascript-pages-frontmatter/pages/string-literal-named-export.js
new file mode 100644
index 0000000000000..d90f8990df3e2
--- /dev/null
+++ b/test/fixtures/javascript-pages-frontmatter/pages/string-literal-named-export.js
@@ -0,0 +1,8 @@
+/* eslint-disable react/display-name */
+import React from 'react'
+
+export const data = {
+ title: 'Foo',
+}
+
+export default () => Foo
diff --git a/test/fixtures/javascript-pages-frontmatter/pages/template-literal-named-export.js b/test/fixtures/javascript-pages-frontmatter/pages/template-literal-named-export.js
new file mode 100644
index 0000000000000..64a25e5532c47
--- /dev/null
+++ b/test/fixtures/javascript-pages-frontmatter/pages/template-literal-named-export.js
@@ -0,0 +1,9 @@
+/* eslint-disable react/display-name */
+import React from 'react'
+
+export const data = {
+ // eslint-disable-next-line
+ title: `Bar`,
+}
+
+export default () => Bar
diff --git a/test/utils/build-page/load-frontmatter.js b/test/utils/build-page/load-frontmatter.js
index 42f72444a6a9e..13cf2dcf7e2de 100644
--- a/test/utils/build-page/load-frontmatter.js
+++ b/test/utils/build-page/load-frontmatter.js
@@ -8,6 +8,13 @@ test('it works for string literal titles', t => {
t.is(data.title, 'Foo')
})
+test('it works for string literal titles declared as a named export', t => {
+ const pagePath =
+ '../../fixtures/javascript-pages-frontmatter/pages/string-literal-named-export.js'
+ const data = loadFrontmatter(pagePath)
+ t.is(data.title, 'Foo')
+})
+
test('it works for template literal titles', t => {
const pagePath =
'../../fixtures/javascript-pages-frontmatter/pages/template-literal.js'
@@ -15,6 +22,13 @@ test('it works for template literal titles', t => {
t.is(data.title, 'Bar')
})
+test('it works for template literal titles declared as a named export', t => {
+ const pagePath =
+ '../../fixtures/javascript-pages-frontmatter/pages/template-literal-named-export.js'
+ const data = loadFrontmatter(pagePath)
+ t.is(data.title, 'Bar')
+})
+
test('it works with array literal values', t => {
const pagePath =
'../../fixtures/javascript-pages-frontmatter/pages/array-literal.js'
@@ -23,6 +37,14 @@ test('it works with array literal values', t => {
t.is(data.titles[1], 'My other title')
})
+test('it works with array literal values declared as a named export', t => {
+ const pagePath =
+ '../../fixtures/javascript-pages-frontmatter/pages/array-literal-named-export.js'
+ const data = loadFrontmatter(pagePath)
+ t.is(data.titles[0], 'My title')
+ t.is(data.titles[1], 'My other title')
+})
+
test('it works with object literal values', t => {
const pagePath =
'../../fixtures/javascript-pages-frontmatter/pages/object-literal.js'
@@ -30,3 +52,11 @@ test('it works with object literal values', t => {
t.is(data.titles.main, 'My title')
t.is(data.titles.sub, 'My other title')
})
+
+test('it works with object literal values declared as a named export', t => {
+ const pagePath =
+ '../../fixtures/javascript-pages-frontmatter/pages/object-literal-named-export.js'
+ const data = loadFrontmatter(pagePath)
+ t.is(data.titles.main, 'My title')
+ t.is(data.titles.sub, 'My other title')
+})