diff --git a/README.md b/README.md
index 37b3df058755b..9432d056ee5ca 100644
--- a/README.md
+++ b/README.md
@@ -274,6 +274,35 @@ module.exports = React.createClass({
})
```
+#### frontmatter and metadata
+Gatsby uses frontmatter and html-frontmatter to pull metadata out of files. This data is typically used in links leading to each page. The most relevant example is a list of blog posts in which you display the title, description, tags, etc. in the form of `{post.title}` in the React.js component.
+
+As seen in our previous markdown file, the title is part of the frontmatter
+```
+---
+title: This is a title
+---
+
+# Hi friends.
+This is a markdown file.
+```
+
+An html example as follows.
+```
+
+
+
Hello World
+```
+
+Gatsby will additionally pull data out of js|jsx files. The files are statically analyzed and an `exports.data` object is pulled. An example as follows.
+```
+exports.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 f07d283a27a47..c90aa6487e92b 100644
--- a/lib/isomorphic/create-routes.js
+++ b/lib/isomorphic/create-routes.js
@@ -132,14 +132,8 @@ module.exports = (files, pagesReq) => {
handler = wrappers[page.file.ext]
page.data = pagesReq(`./${page.requirePath}`)
} else if (reactComponentFileTypes.indexOf(page.file.ext) !== -1) {
- handler = requireComponent(pagesReq(`./${page.requirePath}`))
- page.data = (() => {
- if (pagesReq(`./${page.requirePath}`).metadata) {
- return pagesReq(`./${page.requirePath}`).metadata()
- } else {
- return {}
- }
- })()
+ handler = pagesReq(`./${page.requirePath}`)
+ page.data = page.data = (page.data === undefined) ? {} : page.data
}
// Determine parent template for page.
diff --git a/lib/utils/build-page/load-frontmatter.js b/lib/utils/build-page/load-frontmatter.js
index 398d597acd549..5810bb0db8eca 100644
--- a/lib/utils/build-page/load-frontmatter.js
+++ b/lib/utils/build-page/load-frontmatter.js
@@ -4,6 +4,8 @@ import path from 'path'
import frontMatter from 'front-matter'
import objectAssign from 'object-assign'
import htmlFrontMatter from 'html-frontmatter'
+import * as babylon from 'babylon'
+import traverse from 'babel-traverse'
export default function loadFrontmatter (pagePath: string): {} {
const ext: string = path.extname(pagePath).slice(1)
@@ -21,6 +23,32 @@ export default function loadFrontmatter (pagePath: string): {} {
const html = fs.readFileSync(pagePath, { encoding: 'utf-8' })
// $FlowIssue - https://github.com/facebook/flow/issues/1870
data = objectAssign({}, htmlFrontMatter(html), { body: html })
+ } else if (ext === 'js' || ext === 'jsx') {
+ try {
+ const code = fs.readFileSync(pagePath, { encoding: 'utf-8' })
+ const options = {
+ sourceType: 'module',
+ allowImportExportEverywhere: true,
+ plugins: ['*'] // may only need ['jsx', 'objectRestSpread']?
+ }
+ const ast = babylon.parse(code, options);
+
+ data = {}
+ traverse(ast, {
+ AssignmentExpression(path) {
+ if (path.node.left.type === 'MemberExpression' &&
+ path.node.left.property.name === 'data') {
+ path.node.right.properties.forEach((prop) => {
+ data[prop.key.name] = prop.value.value
+ })
+ }
+ }
+ })
+ } catch (e) {
+ console.log('Failed to parse file')
+ console.log(e)
+ data = {}
+ }
} else {
data = {}
}
diff --git a/package.json b/package.json
index 15822c2e2466a..17117a3fd2ab0 100644
--- a/package.json
+++ b/package.json
@@ -25,6 +25,7 @@
"babel-preset-react": "^6.11.1",
"babel-preset-react-hmre": "^1.1.1",
"babel-preset-stage-0": "^6.5.0",
+ "babel-traverse": "^6.18.0",
"boom": "^2.7.2",
"cjsx-loader": "^3.0.0",
"coffee-loader": "^0.7.2",