diff --git a/.node-version b/.node-version
index dc08cc7b..d53a7e06 100644
--- a/.node-version
+++ b/.node-version
@@ -1 +1 @@
-10.24.1
+12.22.9
diff --git a/src/components/aws-activate-form/ActivateForm.js b/src/components/aws-activate-form/ActivateForm.js
index 88d4e4a3..39cdb2b9 100644
--- a/src/components/aws-activate-form/ActivateForm.js
+++ b/src/components/aws-activate-form/ActivateForm.js
@@ -4,16 +4,13 @@ import { Helmet } from 'react-helmet';
import cn from 'classnames';
import styles from './ActivateForm.module.css';
import buttonStyles from '../buttons/Button.module.css';
-import { event, identify, trackOnLinkedIn } from '../../lib/aptible/analytics';
import { querystring } from '../../lib/util';
+import { event } from '../../lib/aptible/analytics';
+import { submitHubspotForm, HUBSPOT_FORM_AWS_ACTIVATE } from '../../lib/hubspot.js';
const AWS_ACTIVATE_UNIQUE_CODE = `A3POPC`;
const injectedQueryParams = [
- 'utm_campaign',
- 'utm_medium',
- 'utm_source',
- 'utm_term',
AWS_ACTIVATE_UNIQUE_CODE,
];
@@ -28,11 +25,6 @@ const options = [
'None',
];
-const validateEmail = email => {
- if (!email) return { ok: false, message: 'email cannot be empty' };
- return { ok: true, message: '' };
-};
-
export const ActivateForm = ({
id,
eventName='AWS Activate Application Submitted',
@@ -55,13 +47,12 @@ export const ActivateForm = ({
const queryParams = queryString.parse(querystring());
const onSubmit = () => {
- const result = validateEmail(email);
+ const result = submitHubspotForm(HUBSPOT_FORM_AWS_ACTIVATE, email, true);
if (!result.ok) {
setError(result.message);
return;
}
- identify(email);
- event('Email Collected', { formId: id });
+
event(eventName, {
name,
email,
@@ -72,7 +63,6 @@ export const ActivateForm = ({
});
setSubmitted(true);
setError('');
- trackOnLinkedIn();
setTimeout(onSuccess, 500);
};
@@ -88,14 +78,6 @@ export const ActivateForm = ({
/>
-
-
{submitted && (
{successText}
)}
@@ -104,10 +86,8 @@ export const ActivateForm = ({
className={styles.leadFormContainer}
style={{ opacity: submitted ? 0 : 1 }}
>
-
+
{error ? error : ''}
diff --git a/src/components/aws-activate-form/ActivateForm.module.css b/src/components/aws-activate-form/ActivateForm.module.css
index 3bc01993..832030a1 100644
--- a/src/components/aws-activate-form/ActivateForm.module.css
+++ b/src/components/aws-activate-form/ActivateForm.module.css
@@ -6,7 +6,7 @@
overflow-y: scroll;
}
-.leadFormContainer form {
+.leadFormContainer > div {
display: flex;
flex-direction: column;
width: 100%;
@@ -134,7 +134,7 @@
}
@media (--mobile) {
- .leadFormContainer form {
+ .leadFormContainer > div {
flex-direction: column;
justify-content: flex-start;
width: 100%;
diff --git a/src/components/lead-form/LeadForm.js b/src/components/lead-form/LeadForm.js
index e78c1946..7707ea92 100644
--- a/src/components/lead-form/LeadForm.js
+++ b/src/components/lead-form/LeadForm.js
@@ -1,18 +1,9 @@
-import * as queryString from 'query-string';
import React, { useState } from 'react';
import { navigate } from 'gatsby'
import cn from 'classnames';
import styles from './LeadForm.module.css';
import buttonStyles from '../buttons/Button.module.css';
-import { event, identify, trackOnLinkedIn } from '../../lib/aptible/analytics';
-import { querystring } from '../../lib/util';
-
-const utmKeywords = ['utm_campaign', 'utm_medium', 'utm_source', 'utm_term'];
-
-const validateEmail = email => {
- if (!email) return { ok: false, message: 'email cannot be empty' };
- return { ok: true, message: '' };
-};
+import { submitHubspotForm, HUBSPOT_FORM_DEMO } from '../../lib/hubspot.js';
export const LeadForm = ({
id,
@@ -26,20 +17,22 @@ export const LeadForm = ({
const [submitted, setSubmitted] = useState(false);
const [email, setEmail] = useState('');
const [error, setError] = useState('');
- const queryParams = queryString.parse(querystring());
const shouldShowSuccessMessage = !scheduleDemoOnSubmit && submitted;
+
+ const onKeypress = (e) => {
+ if (e.key === 'Enter') {
+ onSubmit();
+ }
+ };
const onSubmit = () => {
- const result = validateEmail(email);
+ const result = submitHubspotForm(HUBSPOT_FORM_DEMO, email, true);
if (!result.ok) {
setError(result.message);
return;
}
- identify(email);
- event('Email Collected', { formId: id });
setSubmitted(true);
setError('');
- trackOnLinkedIn();
onSuccess();
if (scheduleDemoOnSubmit) {
@@ -49,30 +42,18 @@ export const LeadForm = ({
return (
-
-
-
+
{error ? error : ''}
diff --git a/src/components/signup-form/SignupForm.js b/src/components/signup-form/SignupForm.js
index 43930ecf..347861f9 100644
--- a/src/components/signup-form/SignupForm.js
+++ b/src/components/signup-form/SignupForm.js
@@ -1,26 +1,8 @@
-import * as queryString from 'query-string';
import React, { useState } from 'react';
import cn from 'classnames';
import styles from './SignupForm.module.css';
import buttonStyles from '../buttons/Button.module.css';
-import { event, identify, trackOnLinkedIn } from '../../lib/aptible/analytics';
-import { querystring } from '../../lib/util';
-
-const utmKeywords = ['utm_campaign', 'utm_medium', 'utm_source', 'utm_term'];
-const freeEmailDomains = ['gmail.com', 'yahoo.com', 'hotmail.com'];
-
-const validateEmail = (email, allowPersonalEmails) => {
- if (!email) return { ok: false, message: 'email cannot be empty' };
-
- if (!allowPersonalEmails) {
- const emailTokens = email.split('@');
- if (emailTokens.length > 1 && freeEmailDomains.indexOf(emailTokens[1]) !== -1) {
- return { ok: false, message: 'Please use your work email address' };
- }
- }
-
- return { ok: true, message: '' };
-};
+import { submitHubspotForm, HUBSPOT_FORM_PRODUCT_SIGNUP } from '../../lib/hubspot.js';
export const SignupForm = ({
id,
@@ -32,19 +14,22 @@ export const SignupForm = ({
const [submitted, setSubmitted] = useState(false);
const [email, setEmail] = useState('');
const [error, setError] = useState('');
- const queryParams = queryString.parse(querystring());
+
+ const onKeypress = (e) => {
+ if (e.key === 'Enter') {
+ onSubmit();
+ }
+ };
const onSubmit = () => {
- const result = validateEmail(email, allowPersonalEmails);
+ const result = submitHubspotForm(HUBSPOT_FORM_PRODUCT_SIGNUP, email, allowPersonalEmails);
if (!result.ok) {
setError(result.message);
return;
}
- identify(email);
- event('Email Collected', { formId: id });
+
setSubmitted(true);
setError('');
- trackOnLinkedIn();
onSuccess();
// Give time for HubSpot & analytics to fire
@@ -55,30 +40,15 @@ export const SignupForm = ({
return (
diff --git a/src/components/signup-form/SignupForm.module.css b/src/components/signup-form/SignupForm.module.css
index 6ec7b226..936357f5 100644
--- a/src/components/signup-form/SignupForm.module.css
+++ b/src/components/signup-form/SignupForm.module.css
@@ -6,7 +6,7 @@
margin: 0;
transition: opacity 300ms;
}
-.signupFormContainer form {
+.signupFormContainer > div {
display: flex;
flex-direction: row;
justify-content: space-between;
@@ -57,7 +57,7 @@
border-radius: 8px
}
- .signupFormContainer form {
+ .signupFormContainer > div {
flex-direction: column;
justify-content: flex-start;
width: 100%;
diff --git a/src/lib/hubspot.js b/src/lib/hubspot.js
new file mode 100644
index 00000000..45ff9f69
--- /dev/null
+++ b/src/lib/hubspot.js
@@ -0,0 +1,92 @@
+import { analytics, cookies } from './aptible.js';
+import axios from 'axios';
+
+const FREE_EMAIL_DOMAINS = ['gmail.com', 'yahoo.com', 'hotmail.com'];
+const HUBSPOT_ACCOUNT_ID = '20235662';
+const HUBSPOT_COOKIE = 'hubspotutk';
+
+export const HUBSPOT_FORM_PRODUCT_SIGNUP = '9ff54b8a-a71e-464c-95e5-a7fff6511cac';
+export const HUBSPOT_FORM_DEMO = '87365f9e-d16c-4df4-92a1-8cae85d67bd7';
+export const HUBSPOT_FORM_AWS_ACTIVATE = '04eddc8b-cadb-416a-869f-8d5d1f518b40';
+
+const validateEmail = (email, allowPersonalEmails) => {
+ if (!email) return { ok: false, message: 'email cannot be empty' };
+
+ if (!allowPersonalEmails) {
+ const emailTokens = email.split('@');
+ if (emailTokens.length > 1 && FREE_EMAIL_DOMAINS.indexOf(emailTokens[1]) !== -1) {
+ return { ok: false, message: 'Please use your work email address' };
+ }
+ }
+
+ return { ok: true, message: '' };
+};
+
+const generateField = (field, value) => {
+ // Rename gclid for HubSpot
+ if (field === 'gclid') {
+ field = 'hs_google_click_id';
+ }
+
+ return {
+ objectTypeId: '0-1', // 0-1 is used for Contacts
+ name: field,
+ value: value,
+ };
+};
+
+const addUtmsToFields = (fields) => {
+ const utms = {};
+
+ // First grab them from the cookies
+ for (let param of analytics.utmVars) {
+ if (cookies.get(param)) {
+ utms[param] = cookies.get(param);
+ }
+ }
+
+ // Then take them from the URL (and overwrite cookie values if necessary)
+ const urlUtms = analytics.allUtmVars();
+ for (let param of analytics.utmVars) {
+ if (urlUtms[param]) {
+ utms[param] = urlUtms[param];
+ }
+ }
+
+ for (let param in utms) {
+ fields.push(generateField(param, utms[param]));
+ }
+};
+
+export const submitHubspotForm = (formId, email, allowPersonalEmails) => {
+ const result = validateEmail(email, allowPersonalEmails);
+ if (!result.ok) {
+ return result;
+ }
+
+ const payload = {
+ fields: [
+ generateField('email', email)
+ ],
+ context: {
+ pageUri: analytics.currentURL(),
+ pageName: window.document.title,
+ }
+ };
+
+ if (cookies.get(HUBSPOT_COOKIE)) {
+ payload.context.hutk = cookies.get(HUBSPOT_COOKIE)
+ }
+
+ addUtmsToFields(payload.fields);
+
+ analytics.identify(email);
+ analytics.event('Email Collected', { formId: formId });
+ analytics.trackOnLinkedIn();
+
+ // Submit form through the Hubspot API
+ const url = `https://api.hsforms.com/submissions/v3/integration/submit/${HUBSPOT_ACCOUNT_ID}/${formId}`;
+ axios.post(url, payload);
+
+ return result;
+}