mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
Add an example using analytics (#3580)
This patch adds an example of a Next.js app using analytics. A custom document injects the [Segment](https://segment.com) bootstrapping snippet into the `<head>`, allowing "page" and "track" calls to be made. An issue came up in CNA asking how we handle this in our apps (see https://github.com/segmentio/create-next-app/issues/24), so I figure an "official example" could help. NOTE: I am affiliated with Segment.
This commit is contained in:
parent
4965387a3c
commit
9165d753d0
40
examples/with-analytics/README.md
Normal file
40
examples/with-analytics/README.md
Normal file
|
@ -0,0 +1,40 @@
|
|||
[![Deploy to now](https://deploy.now.sh/static/button.svg)](https://deploy.now.sh/?repo=https://github.com/zeit/next.js/tree/master/examples/with-analytics)
|
||||
|
||||
# Example app with analytics
|
||||
|
||||
## How to use
|
||||
|
||||
### Using `create-next-app`
|
||||
|
||||
Download [`create-next-app`](https://github.com/segmentio/create-next-app) to bootstrap the example:
|
||||
|
||||
```
|
||||
npm i -g create-next-app
|
||||
create-next-app --example with-analytics with-analytics-app
|
||||
```
|
||||
|
||||
### Download manually
|
||||
|
||||
Download the example [or clone the repo](https://github.com/zeit/next.js):
|
||||
|
||||
```bash
|
||||
curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/with-analytics
|
||||
cd with-analytics
|
||||
```
|
||||
|
||||
Install it and run:
|
||||
|
||||
```bash
|
||||
yarn
|
||||
yarn dev
|
||||
```
|
||||
|
||||
Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download))
|
||||
|
||||
```bash
|
||||
now
|
||||
```
|
||||
|
||||
## The idea behind the example
|
||||
|
||||
This example shows how to use Next.js along with [Segment Analytics](https://segment.com). A custom document is used in inject the [Segment snippet](https://github.com/segmentio/snippet) into the `<head>` and components fire ["track"](https://segment.com/docs/spec/track/) events based on user actions.
|
14
examples/with-analytics/components/Header.js
Normal file
14
examples/with-analytics/components/Header.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
import React from 'react'
|
||||
import Link from 'next/link'
|
||||
|
||||
export default () => (
|
||||
<header>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><Link href='/'><a>Home</a></Link></li>
|
||||
<li><Link href='/about'><a>About</a></Link></li>
|
||||
<li><Link href='/contact'><a>Contact</a></Link></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
)
|
14
examples/with-analytics/package.json
Normal file
14
examples/with-analytics/package.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"name": "with-analytics",
|
||||
"scripts": {
|
||||
"dev": "next",
|
||||
"build": "next build",
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@segment/snippet": "^4.0.1",
|
||||
"next": "latest",
|
||||
"react": "^16.2.0",
|
||||
"react-dom": "^16.2.0"
|
||||
}
|
||||
}
|
44
examples/with-analytics/pages/_document.js
Normal file
44
examples/with-analytics/pages/_document.js
Normal file
|
@ -0,0 +1,44 @@
|
|||
import React from 'react'
|
||||
import Document, { Head, Main, NextScript } from 'next/document'
|
||||
import * as snippet from '@segment/snippet'
|
||||
|
||||
const {
|
||||
// This write key is associated with https://segment.com/nextjs-example/sources/nextjs.
|
||||
ANALYTICS_WRITE_KEY = 'NPsk1GimHq09s7egCUlv7D0tqtUAU5wa',
|
||||
NODE_ENV = 'development'
|
||||
} = process.env
|
||||
|
||||
export default class extends Document {
|
||||
static getInitialProps ({ renderPage }) {
|
||||
const { html, head, errorHtml, chunks } = renderPage()
|
||||
return { html, head, errorHtml, chunks }
|
||||
}
|
||||
|
||||
renderSnippet () {
|
||||
const opts = {
|
||||
apiKey: ANALYTICS_WRITE_KEY,
|
||||
page: true // Set this to `false` if you want to manually fire `analytics.page()` from within your pages.
|
||||
}
|
||||
|
||||
if (NODE_ENV === 'development') {
|
||||
return snippet.max(opts)
|
||||
}
|
||||
|
||||
return snippet.min(opts)
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<html>
|
||||
<Head>
|
||||
{/* Inject the Segment snippet into the <head> of the document */}
|
||||
<script dangerouslySetInnerHTML={{ __html: this.renderSnippet() }} />
|
||||
</Head>
|
||||
<body>
|
||||
<Main />
|
||||
<NextScript />
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
}
|
9
examples/with-analytics/pages/about.js
Normal file
9
examples/with-analytics/pages/about.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
import React from 'react'
|
||||
import Header from '../components/Header'
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<Header />
|
||||
<h1>This is the About page</h1>
|
||||
</div>
|
||||
)
|
51
examples/with-analytics/pages/contact.js
Normal file
51
examples/with-analytics/pages/contact.js
Normal file
|
@ -0,0 +1,51 @@
|
|||
import React, { Component } from 'react'
|
||||
import Header from '../components/Header'
|
||||
|
||||
export default class extends Component {
|
||||
state = { message: '' }
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div>
|
||||
<Header />
|
||||
<h1>This is the Contact page</h1>
|
||||
<form onSubmit={this.handleSubmit}>
|
||||
<label>
|
||||
<span>Message:</span>
|
||||
<textarea onInput={this.handleInput} value={this.state.message} />
|
||||
</label>
|
||||
<button type='submit'>submit</button>
|
||||
</form>
|
||||
|
||||
<style jsx>{`
|
||||
label span {
|
||||
display: block;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
textarea {
|
||||
min-width: 300px;
|
||||
min-height: 120px;
|
||||
}
|
||||
|
||||
button {
|
||||
margin-top: 12px;
|
||||
display: block;
|
||||
}
|
||||
`}</style>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
handleInput = e => {
|
||||
this.setState({ message: e.target.value })
|
||||
}
|
||||
|
||||
handleSubmit = e => {
|
||||
e.preventDefault()
|
||||
global.analytics.track('Form Submitted', {
|
||||
message: this.state.message
|
||||
})
|
||||
this.setState({ message: '' })
|
||||
}
|
||||
}
|
9
examples/with-analytics/pages/index.js
Normal file
9
examples/with-analytics/pages/index.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
import React from 'react'
|
||||
import Header from '../components/Header'
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<Header />
|
||||
<h1>This is the Home page</h1>
|
||||
</div>
|
||||
)
|
Loading…
Reference in a new issue