{"id":685,"date":"2019-05-02T11:00:30","date_gmt":"2019-05-02T09:00:30","guid":{"rendered":"https:\/\/pagepro.co\/blog\/?p=685"},"modified":"2024-11-25T09:25:21","modified_gmt":"2024-11-25T08:25:21","slug":"getting-started-with-gatsby-styled-components-storybook","status":"publish","type":"post","link":"https:\/\/pagepro.co\/blog\/getting-started-with-gatsby-styled-components-storybook\/","title":{"rendered":"Starting with Gatsby + Styled Components + Storybook"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\" id=\"introduction\">Introduction<\/h2>\n\n\n\n<p>In this article, I will show you how to use Gatsby with Styled Components and Storybook. GatsbyJS is a framework generator built with React and GraphQL. <\/p>\n\n\n\n<p>GatsbyJS is a static-site generator which helps you build blazing fast websites and apps. To front-end side, I will use Styled Components &#8211; the library which allows writing CSS styled in JS. You will also learn about <a href=\"https:\/\/pagepro.co\/services\" target=\"_blank\" rel=\"noreferrer noopener\">Storybook web development<\/a> for React &#8211; a process of creating a UI development environment that you can use to visualize different states of your UI components.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"what-tools-youll-be-using\">What Tools You\u2019ll Be Using<\/h2>\n\n\n\n<ul>\n<li>Gatbsy v2 (<a href=\"https:\/\/www.gatsbyjs.org\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">https:\/\/www.gatsbyjs.org<\/a>)<\/li>\n\n\n\n<li>Styled Components (<a href=\"https:\/\/www.styled-components.com\/ target=\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">https:\/\/www.styled-components.com<\/a>)<\/li>\n\n\n\n<li>Styled System (<a href=\"https:\/\/styled-system.com\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">https:\/\/styled-system.com<\/a>)<\/li>\n\n\n\n<li>Storybook v4 (<a href=\"https:\/\/storybook.js.org\/docs\/guides\/guide-react\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">https:\/\/storybook.js.org\/docs\/guides\/guide-react\/<\/a>)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"why-you-should-get-to-know-gatsby\">Why you should get to know Gatsby?<\/h2>\n\n\n\n<ul>\n<li>Performance &#8211; <a href=\"https:\/\/pagepro.co\/gatsby-development.html\" target=\"_blank\" rel=\"noreferrer noopener\">Gatsby sites<\/a> are couple times faster than similar types of sites<\/li>\n\n\n\n<li>Popularity &#8211; it\u2019s built on React so you got the whole bunch of things that you love about React<\/li>\n\n\n\n<li>Easy to learn &#8211; You can find a lot of well-written tutorials<\/li>\n<\/ul>\n\n\n\n<div class=\"wp-block-code-mind-cta c-cta-block\" style=\"background-color:;color:\"><div class=\"c-cta-block__content\"><p class=\"c-cta-block__title\">Want to build your Gatsby project with top developers? <\/p><div class=\"c-cta-block__action\"><a href=\"https:\/\/pagepro.co\/consultation.html\" class=\"c-cta-block__button ga-cta ga-cta-consultation theme-bg-3\">SCHEDULE A FREE CALL WITH OUR EXPERT. <\/a><\/div><\/div><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"prerequisites\">Prerequisites<\/h2>\n\n\n\n<ul>\n<li>Yarn and Node 10+ installed<\/li>\n\n\n\n<li>Basic understanding of React<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"lets-do-this\">Let\u2019s do this!<\/h2>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step-1-installation\">Step 1: Installation<\/h2>\n\n\n\n<p>I will use simple <a href=\"https:\/\/github.com\/markoradak\/gatsby-starter-storybook\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Gatsby Starter Storybook<\/a> created by markoradak. To create a new project you just clone the starter GitHub repository:<\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"shell\">$ git clone https:\/\/github.com\/markoradak\/gatsby-starter-storybook.git<\/code><\/pre>\n\n\n\n<p>Next, go to the project directory and install packages:<\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"shell\">$ cd gatsby-starter-storybook\n$ yarn<\/code><\/pre>\n\n\n\n<p>When the installation is over and the terminal doesn\u2019t show any errors, start your app:<\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"shell\">$ yarn start || yarn develop<\/code><\/pre>\n\n\n\n<p>Gatsby will start a development environment by default at <em>localhost:8000<\/em>. The server is showing you the starter template:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" loading=\"lazy\" width=\"560\" height=\"333\" src=\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby1.png\" alt=\"Image Component in Storybook\" class=\"wp-image-689\" srcset=\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby1.png 560w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby1-300x178.png 300w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby1-500x297.png 500w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby1-400x238.png 400w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby1-200x119.png 200w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby1-50x30.png 50w\" sizes=\"(max-width: 560px) 100vw, 560px\" \/><\/figure><\/div>\n\n\n<p>To show storybook, use command in the another terminal window:<\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"shell\">$ yarn run storybook<\/code><\/pre>\n\n\n\n<p>If Storybook builds successfully, you should be able to navigate to <em>http:\/\/localhost:6006<\/em> and see the default stories:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" loading=\"lazy\" width=\"760\" height=\"255\" src=\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby2.png\" alt=\"Image Component in Storybook\" class=\"wp-image-691\" srcset=\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby2.png 760w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby2-300x101.png 300w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby2-680x228.png 680w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby2-500x168.png 500w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby2-400x134.png 400w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby2-200x67.png 200w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby2-50x17.png 50w\" sizes=\"(max-width: 760px) 100vw, 760px\" \/><\/figure><\/div>\n\n\n<p>The Image which you see is React component (<em>src\/components\/Image.js<\/em>) loaded to stories (<em>src\/components\/Image.stories.js<\/em>).<\/p>\n\n\n\n<p>How to tell Storybook where to find stories? In <em>.storybook\/config.js<\/em> &#8211; this basic configuration automatically imports all files ending in <em>*.stories.js.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step-2-create-new-component-and-stories\">Step 2. Create new component and stories<\/h2>\n\n\n\n<p>Let\u2019s start with create <em>Header.js<\/em> component and <em>Header.stories.js<\/em>.<br>When I use Storybook, to avoid a mess in my files, I recommend putting React components and stories into directories of the same names.<\/p>\n\n\n\n<div class=\"wp-block-code-mind-alert\" style=\"background-color:;color:\"><p>If you want to do the same with Image component, remember to change his path in index.js and path of SVG image imported to Image.js<\/p><\/div>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" loading=\"lazy\" width=\"340\" height=\"461\" src=\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby3.jpg\" alt=\"Application structure\" class=\"wp-image-704\" srcset=\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby3.jpg 340w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby3-221x300.jpg 221w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby3-200x271.jpg 200w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby3-50x68.jpg 50w\" sizes=\"(max-width: 340px) 100vw, 340px\" \/><\/figure><\/div>\n\n\n<p>Use <em>Styled Components<\/em> to render components with tags and some styles. Assume that the Header will have two variants: default and light.<\/p>\n\n\n\n<p><em>Header.js<\/em><\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"javascript\">import React from 'react';\nimport styled, { css } from 'styled-components';\nimport PropTypes from 'prop-types';\n \nconst HeaderTitleStyled = styled.h1`\n  font-size: 36px;\n  font-weight: 600;\n  color: #fff;\n`;\n \nconst HeaderStyled = styled.header`\n  display: flex;\n  align-items: center;\n  width: 100%;\n  background: #744c9d;\n  padding: 20px 30px;\n  height: 120px;\n \n  ${props => props.light &amp;&amp; css`\n    background: #ccc;\n \n    ${HeaderTitleStyled} {\n      color: #000;\n    }\n  `}\n`;\n \nconst Header = (props) => {\n  return (\n    &lt;HeaderStyled light = {props.light}>\n      &lt;HeaderTitleStyled>\n        Gatsby Project + Storybook\n      &lt;\/HeaderTitleStyled>\n    &lt;\/HeaderStyled>\n  )\n}\n \nHeader.propTypes = {\n  light: PropTypes.bool,\n};\n \nexport default Header;<\/code><\/pre>\n\n\n\n<p>Add Header component to <em>index.js<\/em> and remove unnecessary code from Index page.<\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"javascript\">import React from 'react';\nimport styled from 'styled-components';\nimport Layout from '..\/components\/Layout';\nimport Header from '..\/components\/Header\/Header';\n \nconst Page = styled.div`\n  width: 100%;\n  max-width: 1260px;\n  padding: 0 20px;\n  margin: 0 auto;\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  align-items: center;\n`;\n \nconst IndexPage = () => (\n  &lt;Layout>\n    &lt;Page>\n      &lt;Header\/>\n    &lt;\/Page>\n  &lt;\/Layout>\n);\n \nexport default IndexPage;\n<\/code><\/pre>\n\n\n\n<p>Go to your browser. The default Header should look like:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" loading=\"lazy\" width=\"760\" height=\"100\" src=\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby4.jpg\" alt=\"Header\" class=\"wp-image-717\" srcset=\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby4.jpg 760w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby4-300x39.jpg 300w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby4-680x89.jpg 680w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby4-500x66.jpg 500w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby4-400x53.jpg 400w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby4-200x26.jpg 200w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby4-50x7.jpg 50w\" sizes=\"(max-width: 760px) 100vw, 760px\" \/><\/figure><\/div>\n\n\n<p>Open <em>Header.stories.js<\/em> and write your first story with two variants like this:<\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"javascript\">import React from 'react';\nimport { storiesOf } from '@storybook\/react';\nimport Header from '.\/Header'\n \nstoriesOf('Header', module)\n  .add('default', () => (\n    &lt;Header \/>\n  ))\n  .add('light', () => (\n    &lt;Header light \/>\n  ));\n<\/code><\/pre>\n\n\n\n<p>Now everything is ready. Run your storybook and check the result:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"163\" src=\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby5-1024x163.gif\" alt=\"Heading in Storybook\" class=\"wp-image-719\" srcset=\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby5-1024x163.gif 1024w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby5-300x48.gif 300w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby5-768x122.gif 768w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby5-860x137.gif 860w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby5-680x108.gif 680w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby5-500x79.gif 500w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby5-400x64.gif 400w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby5-200x32.gif 200w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby5-50x8.gif 50w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"step-3-how-to-set-global-styles-in-storybook-environment\">Step 3. How to set global styles in Storybook environment<\/h2>\n\n\n\n<p>As you probably noticed the custom font didn\u2019t load to Storybook. This is because the font is defined in <em>Layout.js<\/em> in App component which is not loaded to Storybook. Located above, there is the GlobalStyle component which is including Styled Reset. These styles are also invisible to Storybook.<\/p>\n\n\n\n<p>So let\u2019s create <em>GlobalStyle.js<\/em> file in <em>\/components<\/em> directory and move there all global styles. Note that <em>GlobalStyle<\/em> was generated by using helper function called <em>createGlobalStyle<\/em>. Normally, styled components are automatically scoped to a local CSS class and therefore isolated from other components. In the case of <em>createGlobalStyle<\/em>, this limitation is removed and things like CSS resets, or base stylesheets can be applied.<\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"javascript\">import { createGlobalStyle } from 'styled-components';\nimport reset from 'styled-reset-advanced';\n \nconst GlobalStyle = createGlobalStyle`\n  ${reset};\n \n  body {\n    font-family: 'Avenir Next', 'Helvetica Neue', 'Helvetica', sans-serif;\n    font-weight: 500;\n  }\n`;\n \nexport default GlobalStyle;<\/code><\/pre>\n\n\n\n<p>In <em>Layout.js<\/em>, remove GlobalStyle component and import it from <em>GlobalStyle.js<\/em>. Get rid of unnecessary styles and imports as well.<\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"javascript\">import React from 'react';\nimport PropTypes from 'prop-types';\nimport Helmet from 'react-helmet';\nimport { StaticQuery, graphql } from 'gatsby';\nimport styled from 'styled-components';\nimport GlobalStyle from '..\/components\/GlobalStyle'\n \nconst App = styled.div``;\n\n...<\/code><\/pre>\n\n\n\n<p>Now, I will add global styles to Storybook. There are a couple of ways that allow you to set global styles. One that I use is decorator. Open <em>.storybook\/config.js<\/em> and import <em>addDecorator<\/em> function which will be responsible for applying our add-on to the system. Next, import React and Fragment (which allows for using multiple children without creating extra DOM elements). Last step is creating decorator which is wrapper a story and the <em>GlobalStyle<\/em> component.<\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"javascript\">import React, { Fragment } from 'react';\nimport { configure, addDecorator } from '@storybook\/react';\nimport { action } from '@storybook\/addon-actions';\nimport GlobalStyle from '..\/src\/components\/GlobalStyle';\n\naddDecorator((story) => (\n  &lt;Fragment>\n    &lt;GlobalStyle\/>\n    {story()}\n  &lt;\/Fragment>\n));<\/code><\/pre>\n\n\n\n<p>Global styles are applied to Storybook.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step-4-create-theme-using-theme-provider\">Step 4. Create theme using Theme Provider<\/h2>\n\n\n\n<p>A theme is helpful if you would like to keep all variables in one place in a project or you need to create several page themes.<\/p>\n\n\n\n<p>In this step, I will create a theme by wrapping all my components in a <em>ThemeProvider<\/em> wrapper component, and by referencing the properties of <em>props.theme<\/em> in our styled-components CSS. Go to the <em>\/assets<\/em> directory and create <em>theme.js<\/em> file. Next, create theme object with some properties:<br><em>theme.js<\/em><\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"javascript\">export const theme = {\n color: {\n   white: '#fff',\n   black: '#000',\n   lightGray: '#ececec',\n   purple: '#744c9d',\n },\n size: {\n   inner: '1260px',\n }\n};<\/code><\/pre>\n\n\n\n<p>Wrap the <em>Layout<\/em> component in a <em>ThemeProvider<\/em> wrapper component:<\/p>\n\n\n\n<div class=\"wp-block-code-mind-alert\" style=\"background-color:;color:\"><p>Note that ThemeProvider doesn\u2019t work like a wrapper &#8211; so we have to use Fragment or div tag to keep multiple children inside.<\/p><\/div>\n\n\n\n<p><em>Layout.js<\/em><\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"javascript\">import styled, { ThemeProvider } from 'styled-components';\nimport theme from '..\/assets\/theme';\n\nconst Layout = ({ children }) => (\n   ...\n   render={data => (\n     &lt;ThemeProvider theme={theme}>\n       &lt;Fragment>\n         &lt;Helmet title={data.site.siteMetadata.title} \/>\n         &lt;GlobalStyle \/>\n         &lt;App>\n           {children}\n         &lt;\/App>\n       &lt;\/Fragment>\n     &lt;\/ThemeProvider>\n   )}\n \/>\n);<\/code><\/pre>\n\n\n\n<p>And use theme properties in styled-components CSS:<br><em>Header.js<\/em><\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"javascript\">const HeaderTitleStyled = styled.h1`\n  font-size: 36px;\n  font-weight: 600;\n  color: ${props => props.theme.color.white};\n`;\n\nconst HeaderStyled = styled.header`\n  display: flex;\n  align-items: center;\n  width: 100%;\n  background: ${props => props.theme.color.purple};\n  padding: 20px 30px;\n  height: 120px;\n\n  ${props => props.light &amp;&amp; css`\n    background: ${props => props.theme.color.lightGray};\n\n    ${HeaderTitleStyled} {\n      color: ${props => props.theme.color.black}\n    }\n  `}\n`;<\/code><\/pre>\n\n\n\n<p><em>index.js<\/em><\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"javascript\">const Page = styled.div`\n  width: 100%;\n  max-width: ${props => props.theme.size.inner};\n  margin: 0 auto;\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  align-items: center;\n`;<\/code><\/pre>\n\n\n\n<p>Any change of property in <em>theme.js<\/em>, will update this property in the component where it was used.<br>Now my app works fine, but Storybook does not read theme property. To fix it, i\u2019ll open Storybook config and add <em>ThemeProvider<\/em> to decorator.<\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"javascript\">import { ThemeProvider } from 'styled-components';\nimport theme from '..\/src\/assets\/theme';\n\naddDecorator((story) => (\n &lt;ThemeProvider theme={theme}>\n   &lt;Fragment>\n     &lt;GlobalStyle\/>\n     {story()}\n   &lt;\/Fragment>\n &lt;\/ThemeProvider>\n));<\/code><\/pre>\n\n\n\n<div class=\"c-newsletter-block-acf\">\n    <p class=\"c-newsletter-block-acf__title c-newsletter__header\">\n        EXPERT INSIGHTS, FRICTIONLESSLY DELIVERED!    <\/p>\n    <p class=\"c-newsletter-block-acf__desc c-newsletter__header\">\n        Curated tech news delivered straight to your inbox every month.\r\n    <\/p>\n    <form method=\"post\" class=\"c-newsletter-block-acf__form js-newsletter-form c-newsletter__action\" name=\"newsletter-block-form\">\n        <input name=\"newsletter-email\" id=\"newsletter-email\" type=\"text\" class=\"c-newsletter-block-acf__input js-newsletter-input\" placeholder=\"Company Email\" \/>\n        <input name=\"newsletter-campaign\" id=\"newsletter-campaign\" type=\"hidden\" value=\"\" \/>\n        <div class=\"c-newsletter-block-acf__group\">\n            <input name=\"consent\" id=\"consent\" type=\"checkbox\" class=\"js-newsletter-consent\" \/>\n            <label class=\"c-newsletter-block-acf__label\" for=\"consent\">I accept the <a href=\"https:\/\/pagepro.co\/privacy-policy\">Privacy Policy<\/a> and agree to process my personal data by Pagepro for marketing purposes.<\/label>\n        <\/div>\n        <input type=\"submit\" class=\"c-newsletter-block-acf__button button js-newsletter-sub ga-newsletter-form-content\" value=\"Sign up\" \/>\n        <p class=\"theme-size-1 js-message-valid is-hidden is-invalid\"><\/p>\n    <\/form>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step-5-typography-dynamic-component-and-styled-system\">Step 5. Typography &#8211; Dynamic Component and Styled System<\/h2>\n\n\n\n<p>Regarding typography, first I think about creating a component for each style of text and import it as needed. However, not every text style has the same HTML tag. Preparing several of the same text styles with other tags don\u2019t seem to be the best solution. Fortunately, Dynamic Component allows you to apply any HTML element to component. To create Typography, use <a href=\"https:\/\/styled-system.com\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Styled System<\/a> &#8211; responsive, theme-based style props for building design systems with React. Styled System works with Styled Component and the most other css-in-js libraries.<\/p>\n\n\n\n<p>First step is to install <em>system-styled<\/em> via yarn. Please run this command in terminal:<\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"shell\">$ yarn add styled-system<\/code><\/pre>\n\n\n\n<p>Create <em>DynamicComponent.js<\/em> in <em>\/components<\/em> directory. Import style functions needed from styled-system and add them to the component&#8217;s styles argument. This component will have four style props available: <em>fontSize<\/em>, <em>color<\/em>, <em>fontWeight<\/em> and <em>lineHeight<\/em>.<\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"javascript\">import React from 'react';\nimport styled from 'styled-components';\nimport { fontSize, color, fontWeight, lineHeight } from 'styled-system';\n\nconst tag = '';\n\nconst StyledDynamicComponent = styled(tag)`\n  ${fontSize}\n  ${color}\n  ${fontWeight}\n  ${lineHeight}\n`;\n\nconst DynamicComponent = ({ tag = 'p', children, ...props }) => {\n  const WithComponent = StyledDynamicComponent.withComponent(tag)\n  return &lt;WithComponent {...props}>{children}&lt;\/WithComponent>\n};\n\nDynamicComponent.defaultProps = {\n  tag: 'p'\n};\n\nexport default DynamicComponent;<\/code><\/pre>\n\n\n\n<p>My <em>DynamicComponent<\/em> is using <em>withComponent<\/em> method that creates a new StyledComponent with any tag. By default I set it to paragraph.<\/p>\n\n\n\n<p>Go to <em>theme.js<\/em> and create <em>textStyles<\/em> object (in the existing theme object) including styles for your heading and text style. With the <em>ThemeProvider<\/em> added, the <em>StyledDynamicComponent<\/em> has access to properties defined in the <em>textStyles<\/em> object.<\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"javascript\"> breakpoints: ['812px', '1024px'],\n textStyles: {\n   heading1: {\n     fontSize: ['32px', '42px', '52px'],\n     color: '#000',\n     fontWeight: 800,\n   },  \n   textStyle1: {\n     fontSize: '16px',\n     color: '#000',\n     fontWeight: 400,\n     lineHeight: '1.4',\n   },\n };\n<\/code><\/pre>\n\n\n\n<p>All <em>styled-system<\/em> functions accept arrays as values to set styles responsively using a mobile-first approach. I defined breakpoints array and <em>fontSize<\/em> array which will set font-size on the corresponding screen width.<\/p>\n\n\n\n<p>Now it\u2019s time to create a heading and text style component using <em>DynamicComponent<\/em>. Go to <em>\/components\/Typography\/Typography.js<\/em><\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"javascript\">import React from 'react';\nimport DynamicComponent from '..\/DynamicComponent';\nimport theme from '..\/..\/assets\/theme';\n\nconst {\n  heading1,\n  textStyle1\n} = theme.textStyles;\n\nexport const Heading1 = props => (\n  &lt;DynamicComponent {...heading1} {...props}>\n    {props.children}\n  &lt;\/DynamicComponent>\n);\n\nexport const TextStyle1 = props => (\n  &lt;DynamicComponent {...textStyle1} {...props}>\n    {props.children}\n  &lt;\/DynamicComponent>\n );<\/code><\/pre>\n\n\n\n<p>Let\u2019s render Heading with tag as props and TextStyle with default tag.<\/p>\n\n\n\n<p><em>index.js<\/em><\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"javascript\">import { Heading1, TextStyle1 } from '..\/components\/Typography\/Typography';\n\nconst Section = styled.section`\n  padding: 50px 0;\n  width: 100%;\n`;\n\nconst IndexPage = () => (\n  &lt;Layout>\n    &lt;Page>\n      &lt;Header\/>\n      &lt;Section>\n        &lt;Heading1 tag=\"h1\">This is Heading1 with H1 tag&lt;\/Heading1>\n        &lt;TextStyle1>This is TextStyle1 with p tag&lt;\/TextStyle1>\n      &lt;\/Section>\n    &lt;\/Page>\n  &lt;\/Layout>\n);<\/code><\/pre>\n\n\n\n<p>As a result, you received a responsive component with the ability to control the tag.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" loading=\"lazy\" width=\"1000\" height=\"375\" src=\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby6-1.gif\" alt=\"Dynamic Component\" class=\"wp-image-739\"\/><\/figure><\/div>\n\n\n<p>You can override your theme styled value or add new property as well.<\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"html\">&lt;TextStyle1 color=\"#fff\" bg=\"#744c9d\">This is TextStyle1 with p tag&lt;\/TextStyle1><\/code><\/pre>\n\n\n\n<p>The result:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" loading=\"lazy\" width=\"760\" height=\"107\" src=\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby7.jpg\" alt=\"Override theme styled values\" class=\"wp-image-725\" srcset=\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby7.jpg 760w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby7-300x42.jpg 300w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby7-680x96.jpg 680w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby7-500x70.jpg 500w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby7-400x56.jpg 400w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby7-200x28.jpg 200w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby7-50x7.jpg 50w\" sizes=\"(max-width: 760px) 100vw, 760px\" \/><\/figure><\/div>\n\n\n<p>Finally, add Typography to stories.<\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"javascript\">import { Heading1, TextStyle1 } from '..\/Typography\/Typography';\n\nstoriesOf('Typography', module)\n  .add('default', () => (\n    &lt;Fragment>\n      &lt;Heading1>Heading1&lt;\/Heading1>\n      &lt;TextStyle1>TextStyle1&lt;\/TextStyle1>\n    &lt;\/Fragment>\n  ));<\/code><\/pre>\n\n\n\n<p>And check your Storybook:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" loading=\"lazy\" width=\"537\" height=\"233\" src=\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby8.jpg\" alt=\"Typography in Storybook\" class=\"wp-image-726\" srcset=\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby8.jpg 537w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby8-300x130.jpg 300w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby8-500x217.jpg 500w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby8-400x174.jpg 400w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby8-200x87.jpg 200w, https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby8-50x22.jpg 50w\" sizes=\"(max-width: 537px) 100vw, 537px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"step-6-make-your-app-responsive\">Step 6. Make your app responsive<\/h2>\n\n\n\n<p>The easiest way to build a responsive app is by using media queries like in normal CSS.<\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"javascript\">const HeaderStyled = styled.header`\n  background: ${props => props.theme.color.black};\n\n   @media only screen and (min-width: 1024px) {\n     background: ${props => props.theme.color.purple};\n   }\n`;\n<\/code><\/pre>\n\n\n\n<p>However, let\u2019s try to make media queries more dynamic. Set breakpoints values in mediaQueries object in <em>theme.js<\/em> and then use them in breakpoint object in new created <em>\/components\/MediaQueries.js<\/em><\/p>\n\n\n\n<p><em>theme.js<\/em><\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"javascript\">export const theme = {\n  ...\n\n  mediaQueries: {\n    tablet: '1024px',\n    phone: '812px',\n },\n};\n<\/code><\/pre>\n\n\n\n<p><em>MediaQueries.js<\/em><\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"javascript\">import theme from '..\/assets\/theme';\n\nconst {\n  tablet,\n  phone\n} = theme.mediaQueries;\n\nexport const bp = {\n  tablet: `min-width: ${tablet}`,\n  phone: `min-width: ${phone}`,\n};\n<\/code><\/pre>\n\n\n\n<p>Change CSS media query to an property of a breakpoint object.<\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"javascript\">const HeaderStyled = styled.header`\n  background: ${props => props.theme.color.black};\n\n  @media (${bp.tablet}) {\n    background: ${props => props.theme.color.purple};\n   }\n`;<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"step-7-gatbsy-image\">Step 7. Gatbsy Image<\/h2>\n\n\n\n<p>One of the most important advantages of Gatsby is it\u2019s work very fast. Many delays in loading pages are caused by too big and non-optimized images. Gatbsy has several useful plugins that help completely optimize images and maintain great performance on our website. The recommended approach is to use <em>gatbsy-image<\/em> &#8211; React component designed to work with Gatsby\u2019s GraphQL queries. It generates multiple sizes and resolutions of each image so you don&#8217;t load large images on a mobile device. You have already installed <em>gatsby-image<\/em> and others needed plugins (<em>gatsby-transformer-sharp<\/em>, <em>gatsby-plugin-sharp<\/em> and <em>gatsby-source-filesystem<\/em>) in the starter (take a look <em>package.json<\/em>).<\/p>\n\n\n\n<p>Add some images to <em>\/assets\/images<\/em>. You can download beautiful and free images from <a href=\"https:\/\/unsplash.com\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">https:\/\/unsplash.com<\/a>.<\/p>\n\n\n\n<p>Navigate to the <em>gatsby-config.js<\/em> and set up a source-filesystem plugin so that your images are available in image queries.<\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"javascript\">{\n  resolve: 'gatsby-source-filesystem',\n  options: {\n    path: `${__dirname}\/src\/assets\/images`,\n    name: 'images',\n  },\n},\n<\/code><\/pre>\n\n\n\n<p><em>Gatbsy-image<\/em> supports two types of responsive images:<\/p>\n\n\n\n<ul>\n<li>fixed (images that have fixed width and height)<\/li>\n\n\n\n<li>fluid (images that stretch when the page is resized).<\/li>\n<\/ul>\n\n\n\n<p><a href=\"https:\/\/www.gatsbyjs.org\/packages\/gatsby-image\/#two-types-of-responsive-images\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">Here<\/a> you find more info about the type of responsive images.<\/p>\n\n\n\n<p>This example shows a gallery of two images using two methods:<br><em>index.js<\/em><\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"javascript\">import React from 'react';\nimport styled from 'styled-components';\nimport { graphql } from 'gatsby';\nimport Img from 'gatsby-image';\n\n...\n\nconst Image = styled.div`\n  max-width: 5000px;\n  margin: 20px 0;\n`\n\nconst IndexPage = ( {data} ) => (\n  &lt;Layout>\n    &lt;Page>\n      &lt;Header\/>\n      &lt;Section>\n        &lt;Heading1 tag=\"h1\">This is Heading1 with H1 tag&lt;\/Heading1>\n        &lt;TextStyle1>This is TextStyle1 with p tag&lt;\/TextStyle1>\n        &lt;Image>\n          &lt;Img fluid={data.pictureOne.childImageSharp.fluid} \/>\n        &lt;\/Image>\n        &lt;Img fixed={data.pictureTwo.childImageSharp.fixed} \/>\n      &lt;\/Section>\n    &lt;\/Page>\n  &lt;\/Layout>\n);\n\nexport const query = graphql`\n  query {\n    pictureOne: file(relativePath: { eq: \"picture-1.jpg\" }) {\n      childImageSharp {\n        fluid(maxWidth: 500, quality: 100) {\n          ...GatsbyImageSharpFluid\n        }\n      }\n    }\n    pictureTwo: file(relativePath: { eq: \"picture-2.jpg\" }) {\n      childImageSharp {\n        fixed(width: 500, quality: 100) {\n          ...GatsbyImageSharpFixed\n        }\n      }\n    }\n  };\n`\n\nexport default IndexPage;<\/code><\/pre>\n\n\n\n<p>The result is:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" loading=\"lazy\" width=\"800\" height=\"520\" src=\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby9-1.gif\" alt=\"Gatsby-image Example\" class=\"wp-image-740\"\/><\/figure><\/div>\n\n\n<p><em>Gatbsy-image<\/em> lazy loads your images with a pretty nice &#8220;blur-up&#8221; effect. If you don\u2019t want to use this effect, you can experiment with others value at the end of fragment.<\/p>\n\n\n\n<div class=\"wp-block-code-mind-alert\" style=\"background-color:;color:\"><p>To learn more, read the Fragments section https:\/\/www.gatsbyjs.org\/packages\/gatsby-image\/<\/p><\/div>\n\n\n\n<p><span style=\"font-weight: 400;\">For example:<\/span><\/p>\n\n\n\n<pre class=\"wp-block-code-mind-code c-code\"><code class=\"javascript\">pictureOne: file(relativePath: { eq: \"picture-1.jpg\" }) {\n  childImageSharp {\n    fluid(maxWidth: 500, quality: 100) {\n      ...GatsbyImageSharpFluid_noBase64\n    }\n  }\n}\npictureTwo: file(relativePath: { eq: \"picture-2.jpg\" }) {\n  childImageSharp {\n    fixed(width: 500, quality: 100) {\n      ...GatsbyImageSharpFixed_tracedSVG\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p>Images are loaded with other effects.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" loading=\"lazy\" width=\"514\" height=\"700\" src=\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/gatsby11.gif\" alt=\"Gatsby-image Example\" class=\"wp-image-744\"\/><\/figure><\/div>\n\n\n<p>Remember that <em>gatbsy-image<\/em> doesn\u2019t support GIF and SVG images. To use GIF image, Gatsby recommends to <a href=\"https:\/\/www.gatsbyjs.org\/docs\/adding-images-fonts-files\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">import the image directly<\/a>. In the case of SVG, creating multiple variants of the image doesn\u2019t make sense because it is vector-based graphics that you can freely scale without losing quality.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"conclusion\">Conclusion<\/h2>\n\n\n\n<p>As you can see, work with Gatsby is pleasant, and the benefits of using it are really great. Hope you enjoyed this article and got inspired to broaden your knowledge about Gatsby \ud83d\ude42 I encourage you to dive into more documentation and tutorials on <a href=\"https:\/\/www.gatsbyjs.org\/docs\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">https:\/\/www.gatsbyjs.org\/docs\/<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"resources\">Resources<\/h2>\n\n\n\n<ul>\n<li><a href=\"https:\/\/www.gatsbyjs.org\/docs\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">https:\/\/www.gatsbyjs.org\/docs<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/medium.com\/harrys-engineering\/creating-a-typography-system-with-react-and-styled-components-ae3661369266\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">https:\/\/medium.com\/harrys-engineering\/creating-a-typography-system-with-react-and-styled-components-ae3661369266<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/medium.com\/@kyle.robert.gill\/ridiculously-easy-image-optimization-with-gatsby-js-59d48e15db6e\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">https:\/\/medium.com\/@kyle.robert.gill\/ridiculously-easy-image-optimization-with-gatsby-js-59d48e15db6e<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Introduction In this article, I will show you how to use Gatsby with Styled Components and Storybook. GatsbyJS is a framework generator built with React and GraphQL. GatsbyJS is a static-site generator which helps you build blazing fast websites and apps. To front-end side, I will use Styled Components &#8211; the library which allows writing [&hellip;]<\/p>\n","protected":false},"author":16,"featured_media":832,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[318],"tags":[85,71,6,53,51,72],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v21.3 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Starting with Gatsby + Styled Components + Storybook - Pagepro<\/title>\n<meta name=\"description\" content=\"Learn how to start using Gatsby with styled-components, and storybook in your next project, and how many great advantages it can bring.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/pagepro.co\/blog\/getting-started-with-gatsby-styled-components-storybook\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Starting with Gatsby + Styled Components + Storybook - Pagepro\" \/>\n<meta property=\"og:description\" content=\"Learn how to start using Gatsby with styled-components, and storybook in your next project, and how many great advantages it can bring.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/pagepro.co\/blog\/getting-started-with-gatsby-styled-components-storybook\/\" \/>\n<meta property=\"og:site_name\" content=\"Pagepro\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/thisispagepro\" \/>\n<meta property=\"article:published_time\" content=\"2019-05-02T09:00:30+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-11-25T08:25:21+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/photo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1600\" \/>\n\t<meta property=\"og:image:height\" content=\"1067\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Jakub Dakowicz\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jakub Dakowicz\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/pagepro.co\/blog\/getting-started-with-gatsby-styled-components-storybook\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/pagepro.co\/blog\/getting-started-with-gatsby-styled-components-storybook\/\"},\"author\":{\"name\":\"Jakub Dakowicz\",\"@id\":\"https:\/\/pagepro.co\/blog\/#\/schema\/person\/66e00cf32ef7d2d1b010523eff380caf\"},\"headline\":\"Starting with Gatsby + Styled Components + Storybook\",\"datePublished\":\"2019-05-02T09:00:30+00:00\",\"dateModified\":\"2024-11-25T08:25:21+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/pagepro.co\/blog\/getting-started-with-gatsby-styled-components-storybook\/\"},\"wordCount\":1625,\"publisher\":{\"@id\":\"https:\/\/pagepro.co\/blog\/#organization\"},\"keywords\":[\"gatsby\",\"gatsbyjs\",\"javascript\",\"react\",\"styled-components\",\"styled-system\"],\"articleSection\":[\"Web Development\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/pagepro.co\/blog\/getting-started-with-gatsby-styled-components-storybook\/\",\"url\":\"https:\/\/pagepro.co\/blog\/getting-started-with-gatsby-styled-components-storybook\/\",\"name\":\"Starting with Gatsby + Styled Components + Storybook - Pagepro\",\"isPartOf\":{\"@id\":\"https:\/\/pagepro.co\/blog\/#website\"},\"datePublished\":\"2019-05-02T09:00:30+00:00\",\"dateModified\":\"2024-11-25T08:25:21+00:00\",\"description\":\"Learn how to start using Gatsby with styled-components, and storybook in your next project, and how many great advantages it can bring.\",\"breadcrumb\":{\"@id\":\"https:\/\/pagepro.co\/blog\/getting-started-with-gatsby-styled-components-storybook\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/pagepro.co\/blog\/getting-started-with-gatsby-styled-components-storybook\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/pagepro.co\/blog\/getting-started-with-gatsby-styled-components-storybook\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/pagepro.co\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Blog\",\"item\":\"https:\/\/pagepro.co\/blog\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Starting with Gatsby + Styled Components + Storybook\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/pagepro.co\/blog\/#website\",\"url\":\"https:\/\/pagepro.co\/blog\/\",\"name\":\"Pagepro\",\"description\":\"Frictionless Next.js, Expo &amp; Sanity Development Blog\",\"publisher\":{\"@id\":\"https:\/\/pagepro.co\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/pagepro.co\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/pagepro.co\/blog\/#organization\",\"name\":\"Pagepro\",\"url\":\"https:\/\/pagepro.co\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/pagepro.co\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2020\/08\/logo_pagepro-b66d228a1e-1.png\",\"contentUrl\":\"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2020\/08\/logo_pagepro-b66d228a1e-1.png\",\"width\":440,\"height\":200,\"caption\":\"Pagepro\"},\"image\":{\"@id\":\"https:\/\/pagepro.co\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/thisispagepro\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/pagepro.co\/blog\/#\/schema\/person\/66e00cf32ef7d2d1b010523eff380caf\",\"name\":\"Jakub Dakowicz\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/pagepro.co\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/5e0855c6f563f4e1a4a53206089ce0cc?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/5e0855c6f563f4e1a4a53206089ce0cc?s=96&d=mm&r=g\",\"caption\":\"Jakub Dakowicz\"},\"description\":\"Jakub is the Chief Technology Officer at Pagepro, where he leads technical strategy and oversees the architecture of complex web platforms built with Next.js and headless CMS solutions. With nearly nine years at Pagepro and over five years leading the engineering team, he has been instrumental in shaping the company\u2019s architectural standards, development workflows, and scalability practices. Jakub focuses on building robust, composable systems that balance performance, maintainability, and long-term business flexibility. He drives technical decision-making across projects, ensuring that solutions are not only modern, but strategically aligned with client growth.\",\"sameAs\":[\"https:\/\/www.linkedin.com\/in\/jakub-dakowicz-939838102\/\"],\"url\":\"https:\/\/pagepro.co\/blog\/author\/jakub_dakowicz\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Starting with Gatsby + Styled Components + Storybook - Pagepro","description":"Learn how to start using Gatsby with styled-components, and storybook in your next project, and how many great advantages it can bring.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/pagepro.co\/blog\/getting-started-with-gatsby-styled-components-storybook\/","og_locale":"en_US","og_type":"article","og_title":"Starting with Gatsby + Styled Components + Storybook - Pagepro","og_description":"Learn how to start using Gatsby with styled-components, and storybook in your next project, and how many great advantages it can bring.","og_url":"https:\/\/pagepro.co\/blog\/getting-started-with-gatsby-styled-components-storybook\/","og_site_name":"Pagepro","article_publisher":"https:\/\/www.facebook.com\/thisispagepro","article_published_time":"2019-05-02T09:00:30+00:00","article_modified_time":"2024-11-25T08:25:21+00:00","og_image":[{"width":1600,"height":1067,"url":"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2019\/03\/photo.jpg","type":"image\/jpeg"}],"author":"Jakub Dakowicz","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Jakub Dakowicz","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/pagepro.co\/blog\/getting-started-with-gatsby-styled-components-storybook\/#article","isPartOf":{"@id":"https:\/\/pagepro.co\/blog\/getting-started-with-gatsby-styled-components-storybook\/"},"author":{"name":"Jakub Dakowicz","@id":"https:\/\/pagepro.co\/blog\/#\/schema\/person\/66e00cf32ef7d2d1b010523eff380caf"},"headline":"Starting with Gatsby + Styled Components + Storybook","datePublished":"2019-05-02T09:00:30+00:00","dateModified":"2024-11-25T08:25:21+00:00","mainEntityOfPage":{"@id":"https:\/\/pagepro.co\/blog\/getting-started-with-gatsby-styled-components-storybook\/"},"wordCount":1625,"publisher":{"@id":"https:\/\/pagepro.co\/blog\/#organization"},"keywords":["gatsby","gatsbyjs","javascript","react","styled-components","styled-system"],"articleSection":["Web Development"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/pagepro.co\/blog\/getting-started-with-gatsby-styled-components-storybook\/","url":"https:\/\/pagepro.co\/blog\/getting-started-with-gatsby-styled-components-storybook\/","name":"Starting with Gatsby + Styled Components + Storybook - Pagepro","isPartOf":{"@id":"https:\/\/pagepro.co\/blog\/#website"},"datePublished":"2019-05-02T09:00:30+00:00","dateModified":"2024-11-25T08:25:21+00:00","description":"Learn how to start using Gatsby with styled-components, and storybook in your next project, and how many great advantages it can bring.","breadcrumb":{"@id":"https:\/\/pagepro.co\/blog\/getting-started-with-gatsby-styled-components-storybook\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/pagepro.co\/blog\/getting-started-with-gatsby-styled-components-storybook\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/pagepro.co\/blog\/getting-started-with-gatsby-styled-components-storybook\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/pagepro.co\/"},{"@type":"ListItem","position":2,"name":"Blog","item":"https:\/\/pagepro.co\/blog\/"},{"@type":"ListItem","position":3,"name":"Starting with Gatsby + Styled Components + Storybook"}]},{"@type":"WebSite","@id":"https:\/\/pagepro.co\/blog\/#website","url":"https:\/\/pagepro.co\/blog\/","name":"Pagepro","description":"Frictionless Next.js, Expo &amp; Sanity Development Blog","publisher":{"@id":"https:\/\/pagepro.co\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/pagepro.co\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/pagepro.co\/blog\/#organization","name":"Pagepro","url":"https:\/\/pagepro.co\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/pagepro.co\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2020\/08\/logo_pagepro-b66d228a1e-1.png","contentUrl":"https:\/\/pagepro.co\/blog\/wp-content\/uploads\/2020\/08\/logo_pagepro-b66d228a1e-1.png","width":440,"height":200,"caption":"Pagepro"},"image":{"@id":"https:\/\/pagepro.co\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/thisispagepro"]},{"@type":"Person","@id":"https:\/\/pagepro.co\/blog\/#\/schema\/person\/66e00cf32ef7d2d1b010523eff380caf","name":"Jakub Dakowicz","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/pagepro.co\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/5e0855c6f563f4e1a4a53206089ce0cc?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5e0855c6f563f4e1a4a53206089ce0cc?s=96&d=mm&r=g","caption":"Jakub Dakowicz"},"description":"Jakub is the Chief Technology Officer at Pagepro, where he leads technical strategy and oversees the architecture of complex web platforms built with Next.js and headless CMS solutions. With nearly nine years at Pagepro and over five years leading the engineering team, he has been instrumental in shaping the company\u2019s architectural standards, development workflows, and scalability practices. Jakub focuses on building robust, composable systems that balance performance, maintainability, and long-term business flexibility. He drives technical decision-making across projects, ensuring that solutions are not only modern, but strategically aligned with client growth.","sameAs":["https:\/\/www.linkedin.com\/in\/jakub-dakowicz-939838102\/"],"url":"https:\/\/pagepro.co\/blog\/author\/jakub_dakowicz\/"}]}},"acf":[],"_links":{"self":[{"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/posts\/685"}],"collection":[{"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/users\/16"}],"replies":[{"embeddable":true,"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/comments?post=685"}],"version-history":[{"count":127,"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/posts\/685\/revisions"}],"predecessor-version":[{"id":18506,"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/posts\/685\/revisions\/18506"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/media\/832"}],"wp:attachment":[{"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/media?parent=685"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/categories?post=685"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pagepro.co\/blog\/wp-json\/wp\/v2\/tags?post=685"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}