{
    "componentChunkName": "component---pewriebontal-gatsby-theme-novela-src-templates-article-template-tsx",
    "path": "/building-the-new-hopper.com-in-2018",
    "result": {"pageContext":{"article":{"id":"69c3e194-1350-54c9-9c66-6d5bb92af6cd","slug":"/building-the-new-hopper.com-in-2018","secret":false,"title":"Building the new Hopper.com in 2018","author":"Dennis Brotzky","categories":["hopper"],"date":"May 1st, 2018","dateForSEO":"2018-05-01T00:00:00.000Z","timeToRead":4,"excerpt":"Creating a new website for Hopper, one of the top 4 most downloaded travel apps in the U.S, along with Uber, Lyft.","canonical_url":null,"subscription":true,"body":"var _excluded = [\"components\"];\nfunction _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }\nfunction _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }\nfunction _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }\n/* @jsxRuntime classic */\n/* @jsx mdx */\n\nvar _frontmatter = {\n  \"title\": \"Building the new Hopper.com in 2018\",\n  \"author\": \"Dennis Brotzky\",\n  \"date\": \"2018-05-01T00:00:00.000Z\",\n  \"hero\": \"./images/hero-2.jpg\",\n  \"excerpt\": \"Creating a new website for Hopper, one of the top 4 most downloaded travel apps in the U.S, along with Uber, Lyft.\",\n  \"categories\": [\"hopper\"]\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n    props = _objectWithoutProperties(_ref, _excluded);\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"Hello, world! This is a demo post for \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-theme-novela\"), \". Novela is built by the team at \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://narative.co\",\n    \"target\": \"_blank\",\n    \"rel\": \"noreferrer\"\n  }, \"Narative\"), \", and built for everyone that loves the web.\"), mdx(\"p\", null, \"At Narative, we\\u2019ve been fans of Gatsby from day one, using it to build performant and flexible products for both clients and ourselves. With the growing community interest in Gatsby, we hope to create more resources that make it easier for anyone to grasp the power of this incredible tool.\\nAt Narative, we\\u2019ve been fans of Gatsby from day one, using it to build performant and flexible products for both clients and ourselves. With the growing community interest in Gatsby, we hope to create more resources that make it easier for anyone to grasp the power of this incredible tool.\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-js\"\n  }, \"import React from \\\"react\\\";\\nimport { graphql, useStaticQuery } from \\\"gatsby\\\";\\nimport styled from \\\"@emotion/styled\\\";\\n\\nimport * as SocialIcons from \\\"../../icons/social\\\";\\nimport mediaqueries from \\\"@styles/media\\\";\\n\\nconst icons = {\\n  dribbble: SocialIcons.DribbbleIcon,\\n  linkedin: SocialIcons.LinkedinIcon,\\n  twitter: SocialIcons.TwitterIcon,\\n  facebook: SocialIcons.FacebookIcon,\\n  instagram: SocialIcons.InstagramIcon,\\n  github: SocialIcons.GithubIcon,\\n};\\n\\nconst socialQuery = graphql`\\n  {\\n    allSite {\\n      edges {\\n        node {\\n          siteMetadata {\\n            social {\\n              name\\n              url\\n            }\\n          }\\n        }\\n      }\\n    }\\n  }\\n`;\\n\\nfunction SocialLinks({ fill = \\\"#73737D\\\" }: { fill: string }) {\\n  const result = useStaticQuery(socialQuery);\\n  const socialOptions = result.allSite.edges[0].node.siteMetadata.social;\\n\\n  return (\\n    <>\\n      {socialOptions.map(option => {\\n        const Icon = icons[option.name];\\n\\n        return (\\n          <SocialIconContainer\\n            key={option.name}\\n            target=\\\"_blank\\\"\\n            rel=\\\"noopener\\\"\\n            data-a11y=\\\"false\\\"\\n            aria-label={`Link to ${option.name}`}\\n            href={option.url}\\n          >\\n            <Icon fill={fill} />\\n          </SocialIconContainer>\\n        );\\n      })}\\n    </>\\n  );\\n}\\n\")), mdx(\"p\", null, \"This is another paragraph after the code block.\"), mdx(\"h2\", {\n    \"id\": \"this-is-a-secondary-heading\"\n  }, \"This is a secondary heading\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-jsx\"\n  }, \"import React from \\\"react\\\";\\nimport { ThemeProvider } from \\\"theme-ui\\\";\\nimport theme from \\\"./theme\\\";\\n\\nexport default props => (\\n  <ThemeProvider theme={theme}>{props.children}</ThemeProvider>\\n);\\n\")), mdx(\"p\", null, \"At Narative, we\\u2019ve been fans of Gatsby from day one, using it to build performant and flexible products for both clients and ourselves. With the growing community interest in Gatsby, we hope to create more resources that make it easier for anyone to grasp the power of this incredible tool.\"), mdx(\"p\", null, \"In this article I\\u2019ll explain how Gatsby\\u2019s lifecycle works and what the Gatsby specific files are for.\"), mdx(\"p\", null, \"One of the challenges I had when learning Gatsby was trying to understand the Gatsby lifecycle. React introduced me to the concept of a Component Lifecycle, but when I started learning Gatsby I felt at a loss again. I remember looking through example repositories and seeing Gatsby specific files in every project and thinking to myself, \\u201CWhat are these files for? Why are gatsby-node.js, gatsby-browser.js, and gatsby-ssr.js generated in the default starter kit? Can I really delete these files?\\u201D\"), mdx(\"p\", null, \"In this article I\\u2019ll explain the how Gatsby\\u2019s lifecycle works and what the Gatsby specific files are for.\"), mdx(\"h2\", {\n    \"id\": \"how-does-gatsby-work\"\n  }, \"How does Gatsby work?\"), mdx(\"p\", null, \"To understand what these files are for, we must first understand how Gatsby works. Gatsby is a static site generator that pulls data from sources you provide and generates a website/app for you.\"), mdx(\"p\", null, \"Gatsby requires Node to be installed to run the Bootstrap and Build sequences. Under the hood, Gatsby uses Webpack to build and start a development server amongst other things.\"), mdx(\"h3\", {\n    \"id\": \"step-1\"\n  }, \"Step 1\"), mdx(\"p\", null, \"During the Bootstrap sequence, which occurs every time you run \\\\$ gatsby develop, there are about 20 events that fire ranging from validating your gatsby-config.js to building the data schemas and pages for your site. For example, the Bootstrap sequence is where Gatsby will create pages. If you want an in depth look of all 20 Bootstrap steps Swyx shared a fantastic Gist that goes into more detail.\"), mdx(\"h3\", {\n    \"id\": \"step-2\"\n  }, \"Step 2\"), mdx(\"p\", null, \"The Build sequence is very similar to the Bootstrap sequence, except it\\u2019s run with production optimizations and will output static files ready for deployment. Think of it as building your React application in production mode vs development.\"), mdx(\"h3\", {\n    \"id\": \"step-3\"\n  }, \"Step 3\"), mdx(\"p\", null, \"And finally, once the generated files are deployed, Gatsby lives in the browser. Gatsby cleverly generates a static website that turns into a web app after initial load, which extends the lifecycle to the browser.\"), mdx(\"p\", null, \"What\\u2019s important to remember is that Gatsby\\u2019s lifecycle can be aggregated into 3 main sequences:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Bootstrap\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Build\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Browser\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"These three sequences makeup the Gatsby lifecycle.\")), mdx(\"p\", null, \"Parts of the lifecycle are visible when running $ gatsby develop\\nA peak into the Gatsby lifecycle when running $ gatsby develop\\nA peak into the Gatsby lifecycle when running \\\\$ gatsby develop\\nIf you\\u2019re familiar with React and the component lifecycle, Gatsby\\u2019s lifecycle is almost the same concept. Just like React\\u2019s lifecycle, Gatsby exposes hooks for developers to build on top of. Those lifecycle hooks are accessed through Gatsby specific files such as gatsby-node.js, gatsby-browser.js and gatsby-ssr.js.\"), mdx(\"p\", null, \"What are the Gatsby specific files for?\\ngatsby-config.js\\nA place to put all your site configurations such as plugins, metadata, and polyfills. This file is the blueprint of your application and is where Gatsby really shines with its plugin system. When you run $ gatsby develop or $ gatsby build gatsby-config.js is the first file to be read and validated.\"), mdx(\"p\", null, \"Most of your time spent in gatsby-config.js will likely revolve around source plugins, image plugins, offline support, styling options, and site metadata.\"), mdx(\"p\", null, \"gatsby-node.js\\nGatsby runs a Node process when you develop or build your website and uses Webpack under the hood to spin up a development server with hot reloading. During the Node process Gatsby will load plugins, check the cache, bootstrap the website, build the data schema, create pages, and deal with some configuration and data management.\"), mdx(\"p\", null, \"Everything that occurs during the Bootstrap and Build sequences occurs in gatsby-node.js. This means it\\u2019s the perfect place to create pages dynamically based off data from a source plugin or modify Gatsby\\u2019s Webpack or Babel configs.\"), mdx(\"p\", null, \"For example, if you want to move some files manually, such as a Netlify \", \"_\", \"redirects file, a good place to do it is in your gatsby-node.js file at the onPostBuild lifecycle hook.\"), mdx(\"p\", null, \"From experience, most of my time has revolved around handling data and building pages in gatsby-node.js. This file quickly becomes the piping of your entire website.\"), mdx(\"h2\", {\n    \"id\": \"examples-of-gatsby-nodejs-hooks\"\n  }, \"Examples of gatsby-node.js hooks:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"createPages\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"onCreateBabelConfig\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"onCreateWebpackConfig\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"onPostBuild\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"gatsby-ssr.js\")), mdx(\"p\", null, \"When you think Server Side Rendering you think of a server that takes in requests and dynamically builds pages and sends it to the client. Gatsby doesn\\u2019t do that, but it does server side render\\u200A\\u2014\\u200Ait generates all the pages during build time.\"), mdx(\"p\", null, \"Naturally, gatsby-ssr.js allows developers to hook into that lifecycle. In my experience, most use cases revolve around injecting CSS, HTML, or Redux state information into the generated output. For example, if you need to insert third party scripts such as Analytics Tracking or a Pixel it can be done on the onRenderBody gatsby-ssr.js hook.\"), mdx(\"h2\", {\n    \"id\": \"examples-of-gatsby-ssrjs-hooks\"\n  }, \"Examples of gatsby-ssr.js hooks:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"onPreRenderHTML\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"onRenderBody\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"replaceRenderer\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"gatsby-browser.js\")), mdx(\"p\", null, \"Gatsby is a static site that loads a dynamic application after initial load, which means you get the benefits of a static site in a web application. gatsby-browser.js provides convenient hooks to deal with app loading, route updates, service worker updates, scroll positioning, and more.\"), mdx(\"p\", null, \"Everything that occurs after your static site has loaded can be hooked in gatsby-browser.js. For apps that I\\u2019ve built, gatsby-browser.js was mostly used for keeping track of routes, scroll positioning, and sending analytics events.\"), mdx(\"h2\", {\n    \"id\": \"examples-of-gatsby-browserjs-hooks\"\n  }, \"Examples of gatsby-browser.js hooks:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"onClientEntry\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"onRouteUpdate\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"onServiceWorkerInstalled\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"registerServiceWorker\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"shouldUpdateScroll\")), mdx(\"h2\", {\n    \"id\": \"conclusion\"\n  }, \"Conclusion\"), mdx(\"p\", null, \"Gatsby is built with React at its core and shares a common API pattern, the lifecycle. This lifecycle gives developers access to key moments in their website\\u2019s process through specific hooks. For example, adding analytics can be achieved through the Browser lifecycle hook onClientEntry. Gatsby reserves specific filenames as an entry point to access every lifecycle; these files are named gatsby-node.js, gatsby-ssr.js and gatsby-browser.js.\"), mdx(\"p\", null, \"Without the Gatsby lifecycle, it would be impossible to customize and modify your project beyond the base configuration, leaving developers with a rigid and poor developer experience. This power and flexibility has helped us build amazing web projects for clients like Hopper!\"), mdx(\"p\", null, \"Gatsby is a staple within our engineering process at Narative, helping us help our clients build the products they\\u2019ve always dreamed of, and the ones they\\u2019re yet to dream up.\"));\n}\n;\nMDXContent.isMDXComponent = true;","hero":{"full":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAMABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAABQAE/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAABNRGRMMtH/8QAGxAAAgMAAwAAAAAAAAAAAAAAAQIAAxEEEhP/2gAIAQEAAQUC467GHamwa9Zw+rLFOz//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAcEAACAgIDAAAAAAAAAAAAAAAAAQIREGEhMVH/2gAIAQEABj8C82KLp10xt4js5jE//8QAGRABAAMBAQAAAAAAAAAAAAAAAQAhMRFR/9oACAEBAAE/Ibjr1kYh4yyIQt3hGRN5EPHE0JBFq/J//9oADAMBAAIAAwAAABBzz//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABsQAQEBAAMBAQAAAAAAAAAAAAERACExcbHh/9oACAEBAAE/ECZsLAvCM93aY6q3tmRONeALnfANFB+63QToOfMlUKK/vf/Z","aspectRatio":1.6164383561643836,"src":"/static/bbe72d5979171315abda4d281e8557c8/58fe7/hero-2.jpg","srcSet":"/static/bbe72d5979171315abda4d281e8557c8/e0f30/hero-2.jpg 236w,\n/static/bbe72d5979171315abda4d281e8557c8/86afd/hero-2.jpg 472w,\n/static/bbe72d5979171315abda4d281e8557c8/58fe7/hero-2.jpg 944w,\n/static/bbe72d5979171315abda4d281e8557c8/0ff54/hero-2.jpg 1200w","srcWebp":"/static/bbe72d5979171315abda4d281e8557c8/99fbb/hero-2.webp","srcSetWebp":"/static/bbe72d5979171315abda4d281e8557c8/77392/hero-2.webp 236w,\n/static/bbe72d5979171315abda4d281e8557c8/1f177/hero-2.webp 472w,\n/static/bbe72d5979171315abda4d281e8557c8/99fbb/hero-2.webp 944w,\n/static/bbe72d5979171315abda4d281e8557c8/9000d/hero-2.webp 1200w","sizes":"(max-width: 944px) 100vw, 944px"},"regular":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAMABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAABQAE/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAABNRGRMMtH/8QAGxAAAgMAAwAAAAAAAAAAAAAAAQIAAxEEEhP/2gAIAQEAAQUC467GHamwa9Zw+rLFOz//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAcEAACAgIDAAAAAAAAAAAAAAAAAQIREGEhMVH/2gAIAQEABj8C82KLp10xt4js5jE//8QAGRABAAMBAQAAAAAAAAAAAAAAAQAhMRFR/9oACAEBAAE/Ibjr1kYh4yyIQt3hGRN5EPHE0JBFq/J//9oADAMBAAIAAwAAABBzz//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABsQAQEBAAMBAQAAAAAAAAAAAAERACExcbHh/9oACAEBAAE/ECZsLAvCM93aY6q3tmRONeALnfANFB+63QToOfMlUKK/vf/Z","aspectRatio":1.613861386138614,"src":"/static/bbe72d5979171315abda4d281e8557c8/1dc0b/hero-2.jpg","srcSet":"/static/bbe72d5979171315abda4d281e8557c8/3a5ce/hero-2.jpg 163w,\n/static/bbe72d5979171315abda4d281e8557c8/05730/hero-2.jpg 327w,\n/static/bbe72d5979171315abda4d281e8557c8/1dc0b/hero-2.jpg 653w,\n/static/bbe72d5979171315abda4d281e8557c8/f72c7/hero-2.jpg 980w,\n/static/bbe72d5979171315abda4d281e8557c8/0ff54/hero-2.jpg 1200w","srcWebp":"/static/bbe72d5979171315abda4d281e8557c8/0acdf/hero-2.webp","srcSetWebp":"/static/bbe72d5979171315abda4d281e8557c8/ac59e/hero-2.webp 163w,\n/static/bbe72d5979171315abda4d281e8557c8/7660b/hero-2.webp 327w,\n/static/bbe72d5979171315abda4d281e8557c8/0acdf/hero-2.webp 653w,\n/static/bbe72d5979171315abda4d281e8557c8/75470/hero-2.webp 980w,\n/static/bbe72d5979171315abda4d281e8557c8/9000d/hero-2.webp 1200w","sizes":"(max-width: 653px) 100vw, 653px"},"narrow":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAMABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAABQAE/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAABNRGRMMtH/8QAGxAAAgMAAwAAAAAAAAAAAAAAAQIAAxEEEhP/2gAIAQEAAQUC467GHamwa9Zw+rLFOz//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAcEAACAgIDAAAAAAAAAAAAAAAAAQIREGEhMVH/2gAIAQEABj8C82KLp10xt4js5jE//8QAGRABAAMBAQAAAAAAAAAAAAAAAQAhMRFR/9oACAEBAAE/Ibjr1kYh4yyIQt3hGRN5EPHE0JBFq/J//9oADAMBAAIAAwAAABBzz//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABsQAQEBAAMBAQAAAAAAAAAAAAERACExcbHh/9oACAEBAAE/ECZsLAvCM93aY6q3tmRONeALnfANFB+63QToOfMlUKK/vf/Z","aspectRatio":1.6285714285714286,"src":"/static/bbe72d5979171315abda4d281e8557c8/eaa58/hero-2.jpg","srcSet":"/static/bbe72d5979171315abda4d281e8557c8/5a3ee/hero-2.jpg 114w,\n/static/bbe72d5979171315abda4d281e8557c8/41f8f/hero-2.jpg 229w,\n/static/bbe72d5979171315abda4d281e8557c8/eaa58/hero-2.jpg 457w,\n/static/bbe72d5979171315abda4d281e8557c8/c309b/hero-2.jpg 686w,\n/static/bbe72d5979171315abda4d281e8557c8/e3008/hero-2.jpg 914w,\n/static/bbe72d5979171315abda4d281e8557c8/0ff54/hero-2.jpg 1200w","srcWebp":"/static/bbe72d5979171315abda4d281e8557c8/15384/hero-2.webp","srcSetWebp":"/static/bbe72d5979171315abda4d281e8557c8/31fce/hero-2.webp 114w,\n/static/bbe72d5979171315abda4d281e8557c8/e3e25/hero-2.webp 229w,\n/static/bbe72d5979171315abda4d281e8557c8/15384/hero-2.webp 457w,\n/static/bbe72d5979171315abda4d281e8557c8/0258d/hero-2.webp 686w,\n/static/bbe72d5979171315abda4d281e8557c8/64ea2/hero-2.webp 914w,\n/static/bbe72d5979171315abda4d281e8557c8/9000d/hero-2.webp 1200w","sizes":"(max-width: 457px) 100vw, 457px"},"seo":{"src":"/static/bbe72d5979171315abda4d281e8557c8/0ff54/hero-2.jpg"}}},"authors":[{"authorsPage":true,"bio":"Written by You. This is where your author bio lives. Share your work, your\njoys and of course, your Twitter handle.\n","id":"bddd2816-affb-520f-b04d-558cb63fc846","name":"Dennis Brotzky","featured":true,"social":[{"url":"https://unsplash.com"},{"url":"https://stackoverflow.com"},{"url":"https://github.com"},{"url":"https://github.com"},{"url":"https://github.com"},{"url":"mailto:myem@il.com"}],"slug":"/authors/dennis-brotzky","avatar":{"small":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAUGAwT/xAAWAQEBAQAAAAAAAAAAAAAAAAACAQD/2gAMAwEAAhADEAAAAbk7yztNE5nJUoF0QZ//xAAeEAABBAIDAQAAAAAAAAAAAAACAAEDBBETBSEiMv/aAAgBAQABBQLK3lvyrspxoLRCTem5D6ZV+4P/xAAWEQADAAAAAAAAAAAAAAAAAAAAEBH/2gAIAQMBAT8BI//EABYRAAMAAAAAAAAAAAAAAAAAAAAQEf/aAAgBAgEBPwEr/8QAHBAAAgIDAQEAAAAAAAAAAAAAAAECERAScSEx/9oACAEBAAY/AjSlriKj42W1YpJfSHMQ4f/EABwQAAMAAwADAAAAAAAAAAAAAAABESExQVFhcf/aAAgBAQABPyGEtlb+wtoYojIdERR+3pnhEqEn2C23w2LU6P/aAAwDAQACAAMAAAAQfAD9/8QAFxEBAQEBAAAAAAAAAAAAAAAAEQEAEP/aAAgBAwEBPxAZXLTn/8QAFxEBAQEBAAAAAAAAAAAAAAAAAAExEf/aAAgBAgEBPxDK4XUf/8QAHRABAQACAwADAAAAAAAAAAAAAREAITFRcWGhwf/aAAgBAQABPxCzRiklSDOgtbrNvP2YI7ag3DUyCORqJ/HCxBPBMsavY/JgvqJ6GCkrTnpTP//Z","aspectRatio":1,"src":"/static/c7748836a93057c66597ca1a32548a19/fa1ea/dennis-brotzky.jpg","srcSet":"/static/c7748836a93057c66597ca1a32548a19/afb2b/dennis-brotzky.jpg 13w,\n/static/c7748836a93057c66597ca1a32548a19/7c20e/dennis-brotzky.jpg 25w,\n/static/c7748836a93057c66597ca1a32548a19/fa1ea/dennis-brotzky.jpg 50w,\n/static/c7748836a93057c66597ca1a32548a19/03612/dennis-brotzky.jpg 75w,\n/static/c7748836a93057c66597ca1a32548a19/61cdf/dennis-brotzky.jpg 100w,\n/static/c7748836a93057c66597ca1a32548a19/25252/dennis-brotzky.jpg 400w","srcWebp":"/static/c7748836a93057c66597ca1a32548a19/e7b2c/dennis-brotzky.webp","srcSetWebp":"/static/c7748836a93057c66597ca1a32548a19/58718/dennis-brotzky.webp 13w,\n/static/c7748836a93057c66597ca1a32548a19/74aad/dennis-brotzky.webp 25w,\n/static/c7748836a93057c66597ca1a32548a19/e7b2c/dennis-brotzky.webp 50w,\n/static/c7748836a93057c66597ca1a32548a19/ed320/dennis-brotzky.webp 75w,\n/static/c7748836a93057c66597ca1a32548a19/66016/dennis-brotzky.webp 100w,\n/static/c7748836a93057c66597ca1a32548a19/fc32b/dennis-brotzky.webp 400w","sizes":"(max-width: 50px) 100vw, 50px"},"medium":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAUGAwT/xAAWAQEBAQAAAAAAAAAAAAAAAAACAQD/2gAMAwEAAhADEAAAAbk7yztNE5nJUoF0QZ//xAAeEAABBAIDAQAAAAAAAAAAAAACAAEDBBETBSEiMv/aAAgBAQABBQLK3lvyrspxoLRCTem5D6ZV+4P/xAAWEQADAAAAAAAAAAAAAAAAAAAAEBH/2gAIAQMBAT8BI//EABYRAAMAAAAAAAAAAAAAAAAAAAAQEf/aAAgBAgEBPwEr/8QAHBAAAgIDAQEAAAAAAAAAAAAAAAECERAScSEx/9oACAEBAAY/AjSlriKj42W1YpJfSHMQ4f/EABwQAAMAAwADAAAAAAAAAAAAAAABESExQVFhcf/aAAgBAQABPyGEtlb+wtoYojIdERR+3pnhEqEn2C23w2LU6P/aAAwDAQACAAMAAAAQfAD9/8QAFxEBAQEBAAAAAAAAAAAAAAAAEQEAEP/aAAgBAwEBPxAZXLTn/8QAFxEBAQEBAAAAAAAAAAAAAAAAAAExEf/aAAgBAgEBPxDK4XUf/8QAHRABAQACAwADAAAAAAAAAAAAAREAITFRcWGhwf/aAAgBAQABPxCzRiklSDOgtbrNvP2YI7ag3DUyCORqJ/HCxBPBMsavY/JgvqJ6GCkrTnpTP//Z","aspectRatio":1,"src":"/static/c7748836a93057c66597ca1a32548a19/61cdf/dennis-brotzky.jpg","srcSet":"/static/c7748836a93057c66597ca1a32548a19/7c20e/dennis-brotzky.jpg 25w,\n/static/c7748836a93057c66597ca1a32548a19/fa1ea/dennis-brotzky.jpg 50w,\n/static/c7748836a93057c66597ca1a32548a19/61cdf/dennis-brotzky.jpg 100w,\n/static/c7748836a93057c66597ca1a32548a19/59538/dennis-brotzky.jpg 150w,\n/static/c7748836a93057c66597ca1a32548a19/fd013/dennis-brotzky.jpg 200w,\n/static/c7748836a93057c66597ca1a32548a19/25252/dennis-brotzky.jpg 400w","srcWebp":"/static/c7748836a93057c66597ca1a32548a19/66016/dennis-brotzky.webp","srcSetWebp":"/static/c7748836a93057c66597ca1a32548a19/74aad/dennis-brotzky.webp 25w,\n/static/c7748836a93057c66597ca1a32548a19/e7b2c/dennis-brotzky.webp 50w,\n/static/c7748836a93057c66597ca1a32548a19/66016/dennis-brotzky.webp 100w,\n/static/c7748836a93057c66597ca1a32548a19/d9b14/dennis-brotzky.webp 150w,\n/static/c7748836a93057c66597ca1a32548a19/6b183/dennis-brotzky.webp 200w,\n/static/c7748836a93057c66597ca1a32548a19/fc32b/dennis-brotzky.webp 400w","sizes":"(max-width: 100px) 100vw, 100px"},"large":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAUGAwT/xAAWAQEBAQAAAAAAAAAAAAAAAAACAQD/2gAMAwEAAhADEAAAAbk7yztNE5nJUoF0QZ//xAAeEAABBAIDAQAAAAAAAAAAAAACAAEDBBETBSEiMv/aAAgBAQABBQLK3lvyrspxoLRCTem5D6ZV+4P/xAAWEQADAAAAAAAAAAAAAAAAAAAAEBH/2gAIAQMBAT8BI//EABYRAAMAAAAAAAAAAAAAAAAAAAAQEf/aAAgBAgEBPwEr/8QAHBAAAgIDAQEAAAAAAAAAAAAAAAECERAScSEx/9oACAEBAAY/AjSlriKj42W1YpJfSHMQ4f/EABwQAAMAAwADAAAAAAAAAAAAAAABESExQVFhcf/aAAgBAQABPyGEtlb+wtoYojIdERR+3pnhEqEn2C23w2LU6P/aAAwDAQACAAMAAAAQfAD9/8QAFxEBAQEBAAAAAAAAAAAAAAAAEQEAEP/aAAgBAwEBPxAZXLTn/8QAFxEBAQEBAAAAAAAAAAAAAAAAAAExEf/aAAgBAgEBPxDK4XUf/8QAHRABAQACAwADAAAAAAAAAAAAAREAITFRcWGhwf/aAAgBAQABPxCzRiklSDOgtbrNvP2YI7ag3DUyCORqJ/HCxBPBMsavY/JgvqJ6GCkrTnpTP//Z","aspectRatio":1,"src":"/static/c7748836a93057c66597ca1a32548a19/ec46e/dennis-brotzky.jpg","srcSet":"/static/c7748836a93057c66597ca1a32548a19/a2637/dennis-brotzky.jpg 82w,\n/static/c7748836a93057c66597ca1a32548a19/15203/dennis-brotzky.jpg 164w,\n/static/c7748836a93057c66597ca1a32548a19/ec46e/dennis-brotzky.jpg 328w,\n/static/c7748836a93057c66597ca1a32548a19/25252/dennis-brotzky.jpg 400w","srcWebp":"/static/c7748836a93057c66597ca1a32548a19/5a48e/dennis-brotzky.webp","srcSetWebp":"/static/c7748836a93057c66597ca1a32548a19/2d087/dennis-brotzky.webp 82w,\n/static/c7748836a93057c66597ca1a32548a19/29d87/dennis-brotzky.webp 164w,\n/static/c7748836a93057c66597ca1a32548a19/5a48e/dennis-brotzky.webp 328w,\n/static/c7748836a93057c66597ca1a32548a19/fc32b/dennis-brotzky.webp 400w","sizes":"(max-width: 328px) 100vw, 328px"}}}],"categories":["hopper"],"basePath":"/","permalink":"https://novela.narative.co/building-the-new-hopper.com-in-2018/","slug":"/building-the-new-hopper.com-in-2018","id":"69c3e194-1350-54c9-9c66-6d5bb92af6cd","title":"Building the new Hopper.com in 2018","canonicalUrl":null,"mailchimp":true,"next":[{"id":"90ebdb5d-095f-5389-a0fa-b4e377c99ccb","slug":"/why-we-built-a-company-before-building-a-platform","secret":false,"title":"Why we built a company before building a platform","author":"Thiago Costa","categories":["product"],"date":"April 30th, 2018","dateForSEO":"2018-04-30T00:00:00.000Z","timeToRead":3,"excerpt":"Creating a new website for Hopper, one of the top 4 most downloaded travel apps in the U.S, along with Uber, Lyft.","canonical_url":null,"subscription":true,"body":"var _excluded = [\"components\"];\nfunction _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }\nfunction _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }\nfunction _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }\n/* @jsxRuntime classic */\n/* @jsx mdx */\n\nvar _frontmatter = {\n  \"title\": \"Why we built a company before building a platform\",\n  \"author\": \"Thiago Costa\",\n  \"date\": \"2018-04-30T00:00:00.000Z\",\n  \"hero\": \"./images/hero-6.jpg\",\n  \"excerpt\": \"Creating a new website for Hopper, one of the top 4 most downloaded travel apps in the U.S, along with Uber, Lyft.\",\n  \"categories\": [\"product\"]\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n    props = _objectWithoutProperties(_ref, _excluded);\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"Hello, world! This is a demo post for \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-theme-novela\"), \". Novela is built by the team at \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://narative.co\",\n    \"target\": \"_blank\",\n    \"rel\": \"noreferrer\"\n  }, \"Narative\"), \", and built for everyone that loves the web.\"), mdx(\"p\", null, \"In my experience, the challenges that growing companies struggle with rarely stem from a lack of good ideas. Good ideas are everywhere.\\nIn my experience, the challenges that growing companies struggle with rarely stem from a lack of good ideas. Good ideas are everywhere.\\nIn my experience, the challenges that growing companies struggle with rarely stem from a lack of good ideas. Good ideas are everywhere.\"), mdx(\"p\", null, \"In my experience, the challenges that growing companies struggle with rarely stem from a lack of good ideas. Good ideas are everywhere.\"), mdx(\"p\", null, \"But it takes more than good ideas to build and grow a business. It takes people to bring them into reality. Are those people collaborating and sharing their expertise, or are they in conflict and keeping it to themselves?\"), mdx(\"p\", null, \"Do they have the resources necessary to execute on their ideas? Or are they constantly under pressure to pluck only the lowest-hanging fruit through bare minimum means, while putting their greatest ambitions on the back-burner?\"), mdx(\"p\", null, \"These are the circumstances that suffocate creativity and destroy value in an organization. That\\u2019s why I knew that if I was going to start a company, our first product would have to be the company itself.\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-js\"\n  }, \"import React from \\\"react\\\";\\nimport { graphql, useStaticQuery } from \\\"gatsby\\\";\\nimport styled from \\\"@emotion/styled\\\";\\n\\nimport * as SocialIcons from \\\"../../icons/social\\\";\\nimport mediaqueries from \\\"@styles/media\\\";\\n\\nconst icons = {\\n  dribbble: SocialIcons.DribbbleIcon,\\n  linkedin: SocialIcons.LinkedinIcon,\\n  twitter: SocialIcons.TwitterIcon,\\n  facebook: SocialIcons.FacebookIcon,\\n  instagram: SocialIcons.InstagramIcon,\\n  github: SocialIcons.GithubIcon,\\n};\\n\\nconst socialQuery = graphql`\\n  {\\n    allSite {\\n      edges {\\n        node {\\n          siteMetadata {\\n            social {\\n              name\\n              url\\n            }\\n          }\\n        }\\n      }\\n    }\\n  }\\n`;\\n\\nfunction SocialLinks({ fill = \\\"#73737D\\\" }: { fill: string }) {\\n  const result = useStaticQuery(socialQuery);\\n  const socialOptions = result.allSite.edges[0].node.siteMetadata.social;\\n\\n  return (\\n    <>\\n      {socialOptions.map(option => {\\n        const Icon = icons[option.name];\\n\\n        return (\\n          <SocialIconContainer\\n            key={option.name}\\n            target=\\\"_blank\\\"\\n            rel=\\\"noopener\\\"\\n            data-a11y=\\\"false\\\"\\n            aria-label={`Link to ${option.name}`}\\n            href={option.url}\\n          >\\n            <Icon fill={fill} />\\n          </SocialIconContainer>\\n        );\\n      })}\\n    </>\\n  );\\n}\\n\")), mdx(\"p\", null, \"But it takes more than good ideas to build and grow a business. It takes people to bring them into reality. Are those people collaborating and sharing their expertise, or are they in conflict and keeping it to themselves?\"), mdx(\"h1\", {\n    \"id\": \"this-is-a-primary-heading\"\n  }, \"This is a primary heading\"), mdx(\"p\", null, \"Do they have the resources necessary to execute on their ideas? Or are they constantly under pressure to pluck only the lowest-hanging fruit through bare minimum means, while putting their greatest ambitions on the back-burner?\"), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"Blockquotes are very handy in email to emulate reply text.\\nThis line is part of the same quote.\")), mdx(\"p\", null, \"But it takes more than good ideas to build and grow a business. It takes people to bring them into reality. Are those people collaborating and sharing their expertise, or are they in conflict and keeping it to themselves?\"), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"This is a very long line that will still be quoted properly when it wraps. Oh boy let\\u2019s keep writing to make sure this is long enough to actually wrap for everyone. Oh, you can \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"put\"), \" \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"Markdown\"), \" into a blockquote.\")), mdx(\"p\", null, \"These are the circumstances that suffocate creativity and destroy value in an organization. That\\u2019s why I knew that if I was going to start a company, our first product would have to be the company itself. These are the circumstances that suffocate creativity and destroy value in an organization. That\\u2019s why I knew that if I was going to start a company, our first product would have to be the company itself.\"), mdx(\"h2\", {\n    \"id\": \"this-is-a-secondary-heading\"\n  }, \"This is a secondary heading\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-jsx\"\n  }, \"import React from \\\"react\\\";\\nimport { ThemeProvider } from \\\"theme-ui\\\";\\nimport theme from \\\"./theme\\\";\\n\\nexport default props => (\\n  <ThemeProvider theme={theme}>{props.children}</ThemeProvider>\\n);\\n\")), mdx(\"p\", null, \"These are the circumstances that suffocate creativity and destroy value in an organization. That\\u2019s why I knew that if I was going to start a company, our first product would have to be the company itself. These are the circumstances that suffocate creativity and destroy value in an organization. That\\u2019s why I knew that if I was going to start a company, our first product would have to be the company itself. These are the circumstances that suffocate creativity and destroy value in an organization. That\\u2019s why I knew that if I was going to start a company, our first product would have to be the company itself. These are the circumstances that suffocate creativity and destroy value in an organization. That\\u2019s why I knew that if I was going to start a company, our first product would have to be the company itself.\"), mdx(\"hr\", null), mdx(\"p\", null, \"Hyphens\"), mdx(\"hr\", null), mdx(\"p\", null, \"Asterisks\"), mdx(\"hr\", null), mdx(\"p\", null, \"Underscores\"), mdx(\"p\", null, \"These are the circumstances that suffocate creativity and destroy value in an organization. That\\u2019s why I knew that if I was going to start a company, our first product would have to be the company itself. These are the circumstances that suffocate creativity and destroy value in an organization. That\\u2019s why I knew that if I was going to start a company, our first product would have to be the company itself.\"), mdx(\"p\", null, \"Do they have the resources necessary to execute on their ideas? Or are they constantly under pressure to pluck only the lowest-hanging fruit through bare minimum means, while putting their greatest ambitions on the back-burner?\"), mdx(\"p\", null, \"Emphasis, aka italics, with \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"asterisks\"), \" or \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"underscores\"), \".\"), mdx(\"p\", null, \"Strong emphasis, aka bold, with \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"asterisks\"), \" or \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"underscores\"), \".\"), mdx(\"p\", null, \"Combined emphasis with \", mdx(\"strong\", {\n    parentName: \"p\"\n  }, \"asterisks and \", mdx(\"em\", {\n    parentName: \"strong\"\n  }, \"underscores\")), \".\"), mdx(\"p\", null, \"Strikethrough uses two tildes. \", mdx(\"del\", {\n    parentName: \"p\"\n  }, \"Scratch this.\")), mdx(\"ol\", null, mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"First ordered list item\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Another item\\n\\u22C5\\u22C5\", \"*\", \" Unordered sub-list.\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"Actual numbers don\\u2019t matter, just that it\\u2019s a number\\n\\u22C5\\u22C51. Ordered sub-list\"), mdx(\"li\", {\n    parentName: \"ol\"\n  }, \"And another item.\")), mdx(\"p\", null, \"\\u22C5\\u22C5\\u22C5You can have properly indented paragraphs within list items. Notice the blank line above, and the leading spaces (at least one, but we\\u2019ll use three here to also align the raw Markdown).\"), mdx(\"p\", null, \"\\u22C5\\u22C5\\u22C5To have a line break without a paragraph, you will need to use two trailing spaces.\\u22C5\\u22C5\\n\\u22C5\\u22C5\\u22C5Note that this line is separate, but within the same paragraph.\\u22C5\\u22C5\\n\\u22C5\\u22C5\\u22C5(This is contrary to the typical GFM line break behaviour, where trailing spaces are not required.)\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Unordered list can use asterisks\")), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Or minuses\")), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Or pluses\")));\n}\n;\nMDXContent.isMDXComponent = true;","hero":{"full":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAMABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAQD/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAH/2gAMAwEAAhADEAAAAct5iVpVf//EABsQAAICAwEAAAAAAAAAAAAAAAABAhEDEBMx/9oACAEBAAEFAozFkZ0bF7da/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAGBABAAMBAAAAAAAAAAAAAAAAEBEhMYH/2gAIAQEABj8CqTDh/8QAGxAAAwADAQEAAAAAAAAAAAAAAAERITFRQaH/2gAIAQEAAT8h4GIqtCQqo+KFknTNpOzHh//aAAwDAQACAAMAAAAQzB//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAbEAEBAAIDAQAAAAAAAAAAAAABEQAhMVGBYf/aAAgBAQABPxBJwHO5r3JfkTeaYD1kwSgsxNQ7B8MFGVBihn//2Q==","aspectRatio":1.6164383561643836,"src":"/static/9d583e5966cbfdd564f7116b054fee86/58fe7/hero-6.jpg","srcSet":"/static/9d583e5966cbfdd564f7116b054fee86/e0f30/hero-6.jpg 236w,\n/static/9d583e5966cbfdd564f7116b054fee86/86afd/hero-6.jpg 472w,\n/static/9d583e5966cbfdd564f7116b054fee86/58fe7/hero-6.jpg 944w,\n/static/9d583e5966cbfdd564f7116b054fee86/0ff54/hero-6.jpg 1200w","srcWebp":"/static/9d583e5966cbfdd564f7116b054fee86/99fbb/hero-6.webp","srcSetWebp":"/static/9d583e5966cbfdd564f7116b054fee86/77392/hero-6.webp 236w,\n/static/9d583e5966cbfdd564f7116b054fee86/1f177/hero-6.webp 472w,\n/static/9d583e5966cbfdd564f7116b054fee86/99fbb/hero-6.webp 944w,\n/static/9d583e5966cbfdd564f7116b054fee86/9000d/hero-6.webp 1200w","sizes":"(max-width: 944px) 100vw, 944px"},"regular":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAMABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAQD/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAH/2gAMAwEAAhADEAAAAct5iVpVf//EABsQAAICAwEAAAAAAAAAAAAAAAABAhEDEBMx/9oACAEBAAEFAozFkZ0bF7da/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAGBABAAMBAAAAAAAAAAAAAAAAEBEhMYH/2gAIAQEABj8CqTDh/8QAGxAAAwADAQEAAAAAAAAAAAAAAAERITFRQaH/2gAIAQEAAT8h4GIqtCQqo+KFknTNpOzHh//aAAwDAQACAAMAAAAQzB//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAbEAEBAAIDAQAAAAAAAAAAAAABEQAhMVGBYf/aAAgBAQABPxBJwHO5r3JfkTeaYD1kwSgsxNQ7B8MFGVBihn//2Q==","aspectRatio":1.613861386138614,"src":"/static/9d583e5966cbfdd564f7116b054fee86/1dc0b/hero-6.jpg","srcSet":"/static/9d583e5966cbfdd564f7116b054fee86/3a5ce/hero-6.jpg 163w,\n/static/9d583e5966cbfdd564f7116b054fee86/05730/hero-6.jpg 327w,\n/static/9d583e5966cbfdd564f7116b054fee86/1dc0b/hero-6.jpg 653w,\n/static/9d583e5966cbfdd564f7116b054fee86/f72c7/hero-6.jpg 980w,\n/static/9d583e5966cbfdd564f7116b054fee86/0ff54/hero-6.jpg 1200w","srcWebp":"/static/9d583e5966cbfdd564f7116b054fee86/0acdf/hero-6.webp","srcSetWebp":"/static/9d583e5966cbfdd564f7116b054fee86/ac59e/hero-6.webp 163w,\n/static/9d583e5966cbfdd564f7116b054fee86/7660b/hero-6.webp 327w,\n/static/9d583e5966cbfdd564f7116b054fee86/0acdf/hero-6.webp 653w,\n/static/9d583e5966cbfdd564f7116b054fee86/75470/hero-6.webp 980w,\n/static/9d583e5966cbfdd564f7116b054fee86/9000d/hero-6.webp 1200w","sizes":"(max-width: 653px) 100vw, 653px"},"narrow":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAMABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAQD/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAH/2gAMAwEAAhADEAAAAct5iVpVf//EABsQAAICAwEAAAAAAAAAAAAAAAABAhEDEBMx/9oACAEBAAEFAozFkZ0bF7da/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAGBABAAMBAAAAAAAAAAAAAAAAEBEhMYH/2gAIAQEABj8CqTDh/8QAGxAAAwADAQEAAAAAAAAAAAAAAAERITFRQaH/2gAIAQEAAT8h4GIqtCQqo+KFknTNpOzHh//aAAwDAQACAAMAAAAQzB//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAbEAEBAAIDAQAAAAAAAAAAAAABEQAhMVGBYf/aAAgBAQABPxBJwHO5r3JfkTeaYD1kwSgsxNQ7B8MFGVBihn//2Q==","aspectRatio":1.6285714285714286,"src":"/static/9d583e5966cbfdd564f7116b054fee86/eaa58/hero-6.jpg","srcSet":"/static/9d583e5966cbfdd564f7116b054fee86/5a3ee/hero-6.jpg 114w,\n/static/9d583e5966cbfdd564f7116b054fee86/41f8f/hero-6.jpg 229w,\n/static/9d583e5966cbfdd564f7116b054fee86/eaa58/hero-6.jpg 457w,\n/static/9d583e5966cbfdd564f7116b054fee86/c309b/hero-6.jpg 686w,\n/static/9d583e5966cbfdd564f7116b054fee86/e3008/hero-6.jpg 914w,\n/static/9d583e5966cbfdd564f7116b054fee86/0ff54/hero-6.jpg 1200w","srcWebp":"/static/9d583e5966cbfdd564f7116b054fee86/15384/hero-6.webp","srcSetWebp":"/static/9d583e5966cbfdd564f7116b054fee86/31fce/hero-6.webp 114w,\n/static/9d583e5966cbfdd564f7116b054fee86/e3e25/hero-6.webp 229w,\n/static/9d583e5966cbfdd564f7116b054fee86/15384/hero-6.webp 457w,\n/static/9d583e5966cbfdd564f7116b054fee86/0258d/hero-6.webp 686w,\n/static/9d583e5966cbfdd564f7116b054fee86/64ea2/hero-6.webp 914w,\n/static/9d583e5966cbfdd564f7116b054fee86/9000d/hero-6.webp 1200w","sizes":"(max-width: 457px) 100vw, 457px"},"seo":{"src":"/static/9d583e5966cbfdd564f7116b054fee86/0ff54/hero-6.jpg"}}},{"id":"f97e727d-5385-5a7b-839a-8dbbbf1dcf4c","slug":"/understanding-the-gatsby-lifecycle-and-how-it-impacts-yout-developer-experience","secret":false,"title":"Understanding the Gatsby lifecycle and how it impacts yout developer experience","author":"Dennis Brotzky","categories":["gatsby"],"date":"April 29th, 2018","dateForSEO":"2018-04-29T00:00:00.000Z","timeToRead":4,"excerpt":"With the growing community interest in Gatsby, we hope to create more resources that make it easier for anyone to grasp the power of this incredible tool.","canonical_url":null,"subscription":true,"body":"var _excluded = [\"components\"];\nfunction _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }\nfunction _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }\nfunction _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }\n/* @jsxRuntime classic */\n/* @jsx mdx */\n\nvar _frontmatter = {\n  \"title\": \"Understanding the Gatsby lifecycle and how it impacts yout developer experience\",\n  \"author\": \"Dennis Brotzky\",\n  \"date\": \"2018-04-29T00:00:00.000Z\",\n  \"hero\": \"./images/hero-2.jpg\",\n  \"excerpt\": \"With the growing community interest in Gatsby, we hope to create more resources that make it easier for anyone to grasp the power of this incredible tool.\",\n  \"categories\": [\"gatsby\"]\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n    props = _objectWithoutProperties(_ref, _excluded);\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"Hello, world! This is a demo post for \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"gatsby-theme-novela\"), \". Novela is built by the team at \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://narative.co\",\n    \"target\": \"_blank\",\n    \"rel\": \"noreferrer\"\n  }, \"Narative\"), \", and built for everyone that loves the web.\"), mdx(\"p\", null, \"At Narative, we\\u2019ve been fans of Gatsby from day one, using it to build performant and flexible products for both clients and ourselves. With the growing community interest in Gatsby, we hope to create more resources that make it easier for anyone to grasp the power of this incredible tool.\\nAt Narative, we\\u2019ve been fans of Gatsby from day one, using it to build performant and flexible products for both clients and ourselves. With the growing community interest in Gatsby, we hope to create more resources that make it easier for anyone to grasp the power of this incredible tool.\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-js\"\n  }, \"import React from \\\"react\\\";\\nimport { graphql, useStaticQuery } from \\\"gatsby\\\";\\nimport styled from \\\"@emotion/styled\\\";\\n\\nimport * as SocialIcons from \\\"../../icons/social\\\";\\nimport mediaqueries from \\\"@styles/media\\\";\\n\\nconst icons = {\\n  dribbble: SocialIcons.DribbbleIcon,\\n  linkedin: SocialIcons.LinkedinIcon,\\n  twitter: SocialIcons.TwitterIcon,\\n  facebook: SocialIcons.FacebookIcon,\\n  instagram: SocialIcons.InstagramIcon,\\n  github: SocialIcons.GithubIcon,\\n};\\n\\nconst socialQuery = graphql`\\n  {\\n    allSite {\\n      edges {\\n        node {\\n          siteMetadata {\\n            social {\\n              name\\n              url\\n            }\\n          }\\n        }\\n      }\\n    }\\n  }\\n`;\\n\\nfunction SocialLinks({ fill = \\\"#73737D\\\" }: { fill: string }) {\\n  const result = useStaticQuery(socialQuery);\\n  const socialOptions = result.allSite.edges[0].node.siteMetadata.social;\\n\\n  return (\\n    <>\\n      {socialOptions.map(option => {\\n        const Icon = icons[option.name];\\n\\n        return (\\n          <SocialIconContainer\\n            key={option.name}\\n            target=\\\"_blank\\\"\\n            rel=\\\"noopener\\\"\\n            data-a11y=\\\"false\\\"\\n            aria-label={`Link to ${option.name}`}\\n            href={option.url}\\n          >\\n            <Icon fill={fill} />\\n          </SocialIconContainer>\\n        );\\n      })}\\n    </>\\n  );\\n}\\n\")), mdx(\"p\", null, \"This is another paragraph after the code block.\"), mdx(\"h2\", {\n    \"id\": \"this-is-a-secondary-heading\"\n  }, \"This is a secondary heading\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-jsx\"\n  }, \"import React from \\\"react\\\";\\nimport { ThemeProvider } from \\\"theme-ui\\\";\\nimport theme from \\\"./theme\\\";\\n\\nexport default props => (\\n  <ThemeProvider theme={theme}>{props.children}</ThemeProvider>\\n);\\n\")), mdx(\"p\", null, \"At Narative, we\\u2019ve been fans of Gatsby from day one, using it to build performant and flexible products for both clients and ourselves. With the growing community interest in Gatsby, we hope to create more resources that make it easier for anyone to grasp the power of this incredible tool.\"), mdx(\"p\", null, \"In this article I\\u2019ll explain how Gatsby\\u2019s lifecycle works and what the Gatsby specific files are for.\"), mdx(\"p\", null, \"One of the challenges I had when learning Gatsby was trying to understand the Gatsby lifecycle. React introduced me to the concept of a Component Lifecycle, but when I started learning Gatsby I felt at a loss again. I remember looking through example repositories and seeing Gatsby specific files in every project and thinking to myself, \\u201CWhat are these files for? Why are gatsby-node.js, gatsby-browser.js, and gatsby-ssr.js generated in the default starter kit? Can I really delete these files?\\u201D\"), mdx(\"p\", null, \"In this article I\\u2019ll explain the how Gatsby\\u2019s lifecycle works and what the Gatsby specific files are for.\"), mdx(\"h2\", {\n    \"id\": \"how-does-gatsby-work\"\n  }, \"How does Gatsby work?\"), mdx(\"p\", null, \"To understand what these files are for, we must first understand how Gatsby works. Gatsby is a static site generator that pulls data from sources you provide and generates a website/app for you.\"), mdx(\"p\", null, \"Gatsby requires Node to be installed to run the Bootstrap and Build sequences. Under the hood, Gatsby uses Webpack to build and start a development server amongst other things.\"), mdx(\"h3\", {\n    \"id\": \"step-1\"\n  }, \"Step 1\"), mdx(\"p\", null, \"During the Bootstrap sequence, which occurs every time you run \\\\$ gatsby develop, there are about 20 events that fire ranging from validating your gatsby-config.js to building the data schemas and pages for your site. For example, the Bootstrap sequence is where Gatsby will create pages. If you want an in depth look of all 20 Bootstrap steps Swyx shared a fantastic Gist that goes into more detail.\"), mdx(\"h3\", {\n    \"id\": \"step-2\"\n  }, \"Step 2\"), mdx(\"p\", null, \"The Build sequence is very similar to the Bootstrap sequence, except it\\u2019s run with production optimizations and will output static files ready for deployment. Think of it as building your React application in production mode vs development.\"), mdx(\"h3\", {\n    \"id\": \"step-3\"\n  }, \"Step 3\"), mdx(\"p\", null, \"And finally, once the generated files are deployed, Gatsby lives in the browser. Gatsby cleverly generates a static website that turns into a web app after initial load, which extends the lifecycle to the browser.\"), mdx(\"p\", null, \"What\\u2019s important to remember is that Gatsby\\u2019s lifecycle can be aggregated into 3 main sequences:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Bootstrap\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Build\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Browser\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"These three sequences makeup the Gatsby lifecycle.\")), mdx(\"p\", null, \"Parts of the lifecycle are visible when running $ gatsby develop\\nA peak into the Gatsby lifecycle when running $ gatsby develop\\nA peak into the Gatsby lifecycle when running \\\\$ gatsby develop\\nIf you\\u2019re familiar with React and the component lifecycle, Gatsby\\u2019s lifecycle is almost the same concept. Just like React\\u2019s lifecycle, Gatsby exposes hooks for developers to build on top of. Those lifecycle hooks are accessed through Gatsby specific files such as gatsby-node.js, gatsby-browser.js and gatsby-ssr.js.\"), mdx(\"p\", null, \"What are the Gatsby specific files for?\\ngatsby-config.js\\nA place to put all your site configurations such as plugins, metadata, and polyfills. This file is the blueprint of your application and is where Gatsby really shines with its plugin system. When you run $ gatsby develop or $ gatsby build gatsby-config.js is the first file to be read and validated.\"), mdx(\"p\", null, \"Most of your time spent in gatsby-config.js will likely revolve around source plugins, image plugins, offline support, styling options, and site metadata.\"), mdx(\"p\", null, \"gatsby-node.js\\nGatsby runs a Node process when you develop or build your website and uses Webpack under the hood to spin up a development server with hot reloading. During the Node process Gatsby will load plugins, check the cache, bootstrap the website, build the data schema, create pages, and deal with some configuration and data management.\"), mdx(\"p\", null, \"Everything that occurs during the Bootstrap and Build sequences occurs in gatsby-node.js. This means it\\u2019s the perfect place to create pages dynamically based off data from a source plugin or modify Gatsby\\u2019s Webpack or Babel configs.\"), mdx(\"p\", null, \"For example, if you want to move some files manually, such as a Netlify \", \"_\", \"redirects file, a good place to do it is in your gatsby-node.js file at the onPostBuild lifecycle hook.\"), mdx(\"p\", null, \"From experience, most of my time has revolved around handling data and building pages in gatsby-node.js. This file quickly becomes the piping of your entire website.\"), mdx(\"h2\", {\n    \"id\": \"examples-of-gatsby-nodejs-hooks\"\n  }, \"Examples of gatsby-node.js hooks:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"createPages\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"onCreateBabelConfig\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"onCreateWebpackConfig\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"onPostBuild\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"gatsby-ssr.js\")), mdx(\"p\", null, \"When you think Server Side Rendering you think of a server that takes in requests and dynamically builds pages and sends it to the client. Gatsby doesn\\u2019t do that, but it does server side render\\u200A\\u2014\\u200Ait generates all the pages during build time.\"), mdx(\"p\", null, \"Naturally, gatsby-ssr.js allows developers to hook into that lifecycle. In my experience, most use cases revolve around injecting CSS, HTML, or Redux state information into the generated output. For example, if you need to insert third party scripts such as Analytics Tracking or a Pixel it can be done on the onRenderBody gatsby-ssr.js hook.\"), mdx(\"h2\", {\n    \"id\": \"examples-of-gatsby-ssrjs-hooks\"\n  }, \"Examples of gatsby-ssr.js hooks:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"onPreRenderHTML\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"onRenderBody\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"replaceRenderer\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"gatsby-browser.js\")), mdx(\"p\", null, \"Gatsby is a static site that loads a dynamic application after initial load, which means you get the benefits of a static site in a web application. gatsby-browser.js provides convenient hooks to deal with app loading, route updates, service worker updates, scroll positioning, and more.\"), mdx(\"p\", null, \"Everything that occurs after your static site has loaded can be hooked in gatsby-browser.js. For apps that I\\u2019ve built, gatsby-browser.js was mostly used for keeping track of routes, scroll positioning, and sending analytics events.\"), mdx(\"h2\", {\n    \"id\": \"examples-of-gatsby-browserjs-hooks\"\n  }, \"Examples of gatsby-browser.js hooks:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"onClientEntry\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"onRouteUpdate\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"onServiceWorkerInstalled\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"registerServiceWorker\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"shouldUpdateScroll\")), mdx(\"h2\", {\n    \"id\": \"conclusion\"\n  }, \"Conclusion\"), mdx(\"p\", null, \"Gatsby is built with React at its core and shares a common API pattern, the lifecycle. This lifecycle gives developers access to key moments in their website\\u2019s process through specific hooks. For example, adding analytics can be achieved through the Browser lifecycle hook onClientEntry. Gatsby reserves specific filenames as an entry point to access every lifecycle; these files are named gatsby-node.js, gatsby-ssr.js and gatsby-browser.js.\"), mdx(\"p\", null, \"Without the Gatsby lifecycle, it would be impossible to customize and modify your project beyond the base configuration, leaving developers with a rigid and poor developer experience. This power and flexibility has helped us build amazing web projects for clients like Hopper!\"), mdx(\"p\", null, \"Gatsby is a staple within our engineering process at Narative, helping us help our clients build the products they\\u2019ve always dreamed of, and the ones they\\u2019re yet to dream up.\"));\n}\n;\nMDXContent.isMDXComponent = true;","hero":{"full":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAJABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAQFA//EABYBAQEBAAAAAAAAAAAAAAAAAAABAv/aAAwDAQACEAMQAAABfW3m3NEnB//EABoQAAICAwAAAAAAAAAAAAAAAAACAQMQEzH/2gAIAQEAAQUCki42qPxcf//EABYRAQEBAAAAAAAAAAAAAAAAAAABEf/aAAgBAwEBPwGRj//EABYRAQEBAAAAAAAAAAAAAAAAAAABEf/aAAgBAgEBPwG1r//EABcQAAMBAAAAAAAAAAAAAAAAAAABICH/2gAIAQEABj8CNU//xAAbEAACAQUAAAAAAAAAAAAAAAAAAbERITFRkf/aAAgBAQABPyFqJstwC3vhAYDP/9oADAMBAAIAAwAAABC43//EABYRAQEBAAAAAAAAAAAAAAAAAAARAf/aAAgBAwEBPxDGJf/EABYRAQEBAAAAAAAAAAAAAAAAAAARAf/aAAgBAgEBPxDSrf/EAB8QAAIABQUAAAAAAAAAAAAAAAABESExsdFBUWFxkf/aAAgBAQABPxDXSCbS3Iye7ZGFNPDFXvdFzJUf/9k=","aspectRatio":2.205607476635514,"src":"/static/5f8eac72cc66a0e5148406174d0cda0e/58fe7/hero-2.jpg","srcSet":"/static/5f8eac72cc66a0e5148406174d0cda0e/e0f30/hero-2.jpg 236w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/86afd/hero-2.jpg 472w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/58fe7/hero-2.jpg 944w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/02748/hero-2.jpg 1416w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/5c241/hero-2.jpg 1888w","srcWebp":"/static/5f8eac72cc66a0e5148406174d0cda0e/99fbb/hero-2.webp","srcSetWebp":"/static/5f8eac72cc66a0e5148406174d0cda0e/77392/hero-2.webp 236w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/1f177/hero-2.webp 472w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/99fbb/hero-2.webp 944w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/4a492/hero-2.webp 1416w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/b0b8f/hero-2.webp 1888w","sizes":"(max-width: 944px) 100vw, 944px"},"regular":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAJABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAQFA//EABYBAQEBAAAAAAAAAAAAAAAAAAABAv/aAAwDAQACEAMQAAABfW3m3NEnB//EABoQAAICAwAAAAAAAAAAAAAAAAACAQMQEzH/2gAIAQEAAQUCki42qPxcf//EABYRAQEBAAAAAAAAAAAAAAAAAAABEf/aAAgBAwEBPwGRj//EABYRAQEBAAAAAAAAAAAAAAAAAAABEf/aAAgBAgEBPwG1r//EABcQAAMBAAAAAAAAAAAAAAAAAAABICH/2gAIAQEABj8CNU//xAAbEAACAQUAAAAAAAAAAAAAAAAAAbERITFRkf/aAAgBAQABPyFqJstwC3vhAYDP/9oADAMBAAIAAwAAABC43//EABYRAQEBAAAAAAAAAAAAAAAAAAARAf/aAAgBAwEBPxDGJf/EABYRAQEBAAAAAAAAAAAAAAAAAAARAf/aAAgBAgEBPxDSrf/EAB8QAAIABQUAAAAAAAAAAAAAAAABESExsdFBUWFxkf/aAAgBAQABPxDXSCbS3Iye7ZGFNPDFXvdFzJUf/9k=","aspectRatio":2.2027027027027026,"src":"/static/5f8eac72cc66a0e5148406174d0cda0e/1dc0b/hero-2.jpg","srcSet":"/static/5f8eac72cc66a0e5148406174d0cda0e/3a5ce/hero-2.jpg 163w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/05730/hero-2.jpg 327w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/1dc0b/hero-2.jpg 653w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/f72c7/hero-2.jpg 980w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/6e4a3/hero-2.jpg 1306w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/5c241/hero-2.jpg 1888w","srcWebp":"/static/5f8eac72cc66a0e5148406174d0cda0e/0acdf/hero-2.webp","srcSetWebp":"/static/5f8eac72cc66a0e5148406174d0cda0e/ac59e/hero-2.webp 163w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/7660b/hero-2.webp 327w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/0acdf/hero-2.webp 653w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/75470/hero-2.webp 980w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/68d47/hero-2.webp 1306w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/b0b8f/hero-2.webp 1888w","sizes":"(max-width: 653px) 100vw, 653px"},"narrow":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAJABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAQFA//EABYBAQEBAAAAAAAAAAAAAAAAAAABAv/aAAwDAQACEAMQAAABfW3m3NEnB//EABoQAAICAwAAAAAAAAAAAAAAAAACAQMQEzH/2gAIAQEAAQUCki42qPxcf//EABYRAQEBAAAAAAAAAAAAAAAAAAABEf/aAAgBAwEBPwGRj//EABYRAQEBAAAAAAAAAAAAAAAAAAABEf/aAAgBAgEBPwG1r//EABcQAAMBAAAAAAAAAAAAAAAAAAABICH/2gAIAQEABj8CNU//xAAbEAACAQUAAAAAAAAAAAAAAAAAAbERITFRkf/aAAgBAQABPyFqJstwC3vhAYDP/9oADAMBAAIAAwAAABC43//EABYRAQEBAAAAAAAAAAAAAAAAAAARAf/aAAgBAwEBPxDGJf/EABYRAQEBAAAAAAAAAAAAAAAAAAARAf/aAAgBAgEBPxDSrf/EAB8QAAIABQUAAAAAAAAAAAAAAAABESExsdFBUWFxkf/aAAgBAQABPxDXSCbS3Iye7ZGFNPDFXvdFzJUf/9k=","aspectRatio":2.235294117647059,"src":"/static/5f8eac72cc66a0e5148406174d0cda0e/eaa58/hero-2.jpg","srcSet":"/static/5f8eac72cc66a0e5148406174d0cda0e/5a3ee/hero-2.jpg 114w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/41f8f/hero-2.jpg 229w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/eaa58/hero-2.jpg 457w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/c309b/hero-2.jpg 686w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/e3008/hero-2.jpg 914w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/5c241/hero-2.jpg 1888w","srcWebp":"/static/5f8eac72cc66a0e5148406174d0cda0e/15384/hero-2.webp","srcSetWebp":"/static/5f8eac72cc66a0e5148406174d0cda0e/31fce/hero-2.webp 114w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/e3e25/hero-2.webp 229w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/15384/hero-2.webp 457w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/0258d/hero-2.webp 686w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/64ea2/hero-2.webp 914w,\n/static/5f8eac72cc66a0e5148406174d0cda0e/b0b8f/hero-2.webp 1888w","sizes":"(max-width: 457px) 100vw, 457px"},"seo":{"src":"/static/5f8eac72cc66a0e5148406174d0cda0e/0ff54/hero-2.jpg"}}}]}},
    "staticQueryHashes": ["1232052689","1491088328","1921650733","2068910035","2444214635","2744905544"]}