-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Adds email capture to bottom of blog #3333
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
Merged
Merged
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
253e3be
Adds email capture to bottom of blog
benjaminhoffman 19c6d10
Adds email capture to bottom of blog
benjaminhoffman dd77175
Adds Mailchimp functionality
benjaminhoffman b1c4eaf
Merge branch 'emailcapture' of github.com:benjaminhoffman/gatsby into…
benjaminhoffman 78f3c4b
Merge remote-tracking branch 'upstream/master' into emailcapture
benjaminhoffman a860856
Merge remote-tracking branch 'upstream/master' into emailcapture
benjaminhoffman 3066ff5
Refactors postEmailToMailchimp method, updates cc
benjaminhoffman 0d6f9f9
updates rhythm css, installs & uses validator module
benjaminhoffman 9d1df14
Merge branch 'master' into emailcapture
benjaminhoffman 00b2fd8
Fiddle with design
KyleAMathews File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,7 @@ | |
| "author": "Kyle Mathews <[email protected]>", | ||
| "dependencies": { | ||
| "bluebird": "^3.5.1", | ||
| "email-validator": "^1.1.1", | ||
| "gatsby": "^1.9.77", | ||
| "gatsby-image": "^1.0.14", | ||
| "gatsby-link": "^1.6.23", | ||
|
|
@@ -38,6 +39,7 @@ | |
| "gatsby-transformer-yaml": "^1.5.7", | ||
| "graphql-request": "^1.4.0", | ||
| "gray-percentage": "^2.0.0", | ||
| "jsonp": "^0.2.1", | ||
| "limax": "^1.5.0", | ||
| "lodash": "^4.16.6", | ||
| "mitt": "^1.1.2", | ||
|
|
@@ -47,7 +49,8 @@ | |
| "typeface-space-mono": "^0.0.40", | ||
| "typeface-spectral": "^0.0.40", | ||
| "typography-breakpoint-constants": "^0.15.10", | ||
| "typography-plugin-code": "^0.16.11" | ||
| "typography-plugin-code": "^0.16.11", | ||
| "validator": "^9.2.0" | ||
| }, | ||
| "keywords": [ | ||
| "gatsby" | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,160 @@ | ||
| import React from "react" | ||
| import { rhythm } from "../utils/typography" | ||
| import presets from "../utils/presets" | ||
| import jsonp from "jsonp" | ||
| import { validate } from "email-validator" | ||
| import { css } from "glamor" | ||
|
|
||
| let stripeAnimation = css.keyframes({ | ||
| "0%": { backgroundPosition: `0 0` }, | ||
| "100%": { backgroundPosition: `30px 60px` }, | ||
| }) | ||
|
|
||
| // Mailchimp endpoint | ||
| // From: https://us17.admin.mailchimp.com/lists/integration/embeddedcode?id=XXXXXX | ||
| // Where `XXXXXX` is the MC list ID | ||
| // Note: we change `/post` to `/post-json` | ||
| const MAILCHIMP_URL = `https://gatsbyjs.us17.list-manage.com/subscribe/post-json?u=1dc33f19eb115f7ebe4afe5ee&id=f366064ba7` | ||
|
|
||
| class EmailCaptureForm extends React.Component { | ||
| constructor() { | ||
| super() | ||
| this.state = { | ||
| email: ``, | ||
| } | ||
| } | ||
|
|
||
| // Update state each time user edits their email address | ||
| _handleEmailChange = e => { | ||
| this.setState({ email: e.target.value }) | ||
| } | ||
|
|
||
| // Using jsonp, post to MC server & handle its response | ||
| _postEmailToMailchimp = url => { | ||
| // jsonp lib takes an `endpoint`, {options}, & callback | ||
| jsonp(url, { param: `c` }, (err, data) => { | ||
| // network failures, timeouts, etc | ||
| if (err) { | ||
| this.setState({ | ||
| status: `error`, | ||
| msg: err, | ||
| }) | ||
|
|
||
| // Mailchimp errors & failures | ||
| } else if (data.result !== `success`) { | ||
| this.setState({ | ||
| status: `error`, | ||
| msg: data.msg, | ||
| }) | ||
|
|
||
| // Posted email successfully to Mailchimp | ||
| } else { | ||
| this.setState({ | ||
| status: `success`, | ||
| msg: data.msg, | ||
| }) | ||
| } | ||
| }) | ||
| } | ||
|
|
||
| // On form submit, validate email | ||
| // then jsonp to Mailchimp, and update state | ||
| _handleFormSubmit = e => { | ||
| e.preventDefault() | ||
| e.stopPropagation() | ||
|
|
||
| // If email is not valid, break early | ||
| if (!validate(this.state.email)) { | ||
| this.setState({ | ||
| status: `error`, | ||
| msg: `"${this.state.email}" is not a valid email address`, | ||
| }) | ||
| return | ||
| } | ||
|
|
||
| // Construct the url for our jsonp request | ||
| // Query params must be in CAPS | ||
| // Capture pathname for better email targeting | ||
| const url = `${MAILCHIMP_URL} | ||
| &EMAIL=${encodeURIComponent(this.state.email)} | ||
| &PATHNAME=${window.location.pathname} | ||
| ` | ||
|
|
||
| this.setState( | ||
| { | ||
| msg: null, | ||
| status: `sending`, | ||
| }, | ||
| // jsonp request as setState callback | ||
| this._postEmailToMailchimp(url) | ||
| ) | ||
| } | ||
|
|
||
| render() { | ||
| return ( | ||
| <div | ||
| css={{ | ||
| borderTop: `2px solid ${presets.brandLight}`, | ||
| marginTop: rhythm(3), | ||
| paddingTop: `${rhythm(1)}`, | ||
| }} | ||
| > | ||
| {this.state.status === `success` ? ( | ||
| <div>Thank you! Youʼll receive your first email shortly.</div> | ||
| ) : ( | ||
| <div> | ||
| <p>Enjoyed this post? Receive the next one in your inbox!</p> | ||
| <form | ||
| id="email-capture" | ||
| method="post" | ||
| noValidate | ||
| css={{ margin: 0 }} | ||
| > | ||
| <div> | ||
| <input | ||
| type="email" | ||
| name="email" | ||
| placeholder="[email protected]" | ||
| onChange={this._handleEmailChange} | ||
| css={{ | ||
| padding: rhythm(1 / 2), | ||
| width: `250px`, | ||
| color: presets.bodyColor, | ||
| }} | ||
| /> | ||
| <button | ||
| type="submit" | ||
| onClick={this._handleFormSubmit} | ||
| css={{ | ||
| borderRadius: `2px`, | ||
| border: `1px solid ${presets.brand}`, | ||
| cursor: `pointer`, | ||
| padding: rhythm(1 / 2), | ||
| margin: `${rhythm(1 / 2)} 0 0 ${rhythm(1 / 2)}`, | ||
| ":hover": { | ||
| backgroundSize: `30px 30px`, | ||
| backgroundColor: presets.brand, | ||
| backgroundImage: `linear-gradient(45deg, rgba(0,0,0, 0.1) 25%, transparent 25%, transparent 50%, rgba(0,0,0, 0.1) 50%, rgba(0,0,0, 0.1) 75%, transparent 75%, transparent)`, | ||
| color: `#fff`, | ||
| animation: `${stripeAnimation} 2.8s linear infinite`, | ||
| }, | ||
| }} | ||
| > | ||
| Subscribe | ||
| </button> | ||
| {this.state.status === `error` && ( | ||
| <div | ||
| dangerouslySetInnerHTML={{ __html: this.state.msg }} | ||
| css={{ marginTop: `${rhythm(1 / 2)}` }} | ||
| /> | ||
| )} | ||
| </div> | ||
| </form> | ||
| </div> | ||
| )} | ||
| </div> | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| export default EmailCaptureForm | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should i make these env vars?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ideally this should be a prop passed into the component named mailChimpUrl
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thought about that too but after getting this merged, I was thinking of adding the form on other non-blog pages. then each parent component will need to pass the
MAILCHIMP_URLas a prop, which gets super messy.thoughts on env var? or just keeping this URL in this component? imagine having this component in a bunch of different templates in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd just leave it hard-coded. It's not really a secret nor are we trying to make this component reusable for multiple lists atm. It's trivial to refactor later.