{"pageProps":{"title":"Criando um projeto do zero com Next.js, typescript e styled-components","description":"Vamos juntos configurar um projeto do zero, passo a passo, até está pronto para ser usado.","thumbnailUrl":"https://blogdomat.vercel.app/api/thumbnail.png?title=Criando um projeto do zero com Next.js, typescript e styled-components&icon=https://cdn.worldvectorlogo.com/logos/typescript.svg","slug":"5-criando-projeto-nextjs-com-typescript-e-styled-components","content":"

O que é Next.js?

\n

Next.js é uma estrutura React para desenvolver aplicativos e sites JavaScript de uma e várias páginas.

\n

Criando o projeto e instalando as dependências

\n

Para criar o projeto utilize o comando

\n
yarn create next-app nome-do-projeto\n\n# Acesse a pasta do projeto e adicione suporte ao typescript\ncd nome-do-projeto\nyarn add typescript @types/react @types/node -D
\n

Agora vamos limpar o projeto, deletando os arquivos que não vamos usar, a estrutura de pastas deverá ficar igual a imagem a seguir:

\n

\"Como

\n

Após você deverá renomear os arquivos pages/_app.js e pages/index.js para typescript, e fazer as seguintes alterações

\n

Arquivo: pages/_app.tsx antes:

\n
import '../styles/globals.css'\n\nfunction MyApp({ Component, pageProps }) {\n  return <Component {...pageProps} />\n}\n\nexport default MyApp
\n

Arquivo: pages/_app.tsx depois:

\n
import React from 'react'\nimport { AppProps } from 'next/app'\n\nconst MyApp: React.FC<AppProps> = ({ Component, pageProps }) => {\n  return <Component {...pageProps} />\n}\n\nexport default MyApp\n
\n

Arquivo pages/index.tsx:

\n
import React from 'react'\nimport Head from 'next/head'\n\nconst Home: React.FC = () => {\n  return (\n    <>\n      <Head>\n        <title>Create Next App</title>\n      </Head>\n\n      <main>\n\n      </main>\n    </>\n  )\n}\n\nexport default Home
\n

Vamos instalar o eslint e o prettier

\n

O eslint e prettier vai cuidar para que o código ficar legivel e padronizado

\n
# Instale o eslint\nyarn add eslint -D\n\n# Instale o prettier\nyarn add prettier eslint-plugin-prettier eslint-config-prettier -D\n\n# Inicie o eslint para gerar o arquivo de configurações\nyarn eslint --init
\n

A seguir tem a imagem de como deverá ser a configuração do eslint

\n

\"Configuração

\n

Confirme a instalação com o npm e aguarde terminar, após delete o arquivo package-lock.json e rode yarn para instalar novamente.

\n

Agora abra o arquivo .eslintrc.json e faça as adições a seguir:

\n
{\n  "env": {\n    "browser": true,\n    "es2021": true,\n    "node": true,\n    "jest": true\n  },\n  "extends": [\n    "plugin:react/recommended",\n    "standard",\n    "plugin:@typescript-eslint/recommended",\n    "prettier/@typescript-eslint",\n    "prettier/standard",\n    "prettier/react"\n  ],\n  "parser": "@typescript-eslint/parser",\n  "parserOptions": {\n    "ecmaFeatures": {\n      "jsx": true\n    },\n    "ecmaVersion": 12,\n    "sourceType": "module"\n  },\n  "plugins": [\n    "react",\n    "@typescript-eslint",\n    "prettier"\n  ],\n  "rules": {\n    "prettier/prettier": "error",\n    "space-before-function-paren": "off",\n    "react/prop-types": "off"\n  }\n}
\n

Crie o arquivo .eslintignore na raiz do projeto com o conteúdo a seguir

\n
node_modules\n.next\n/*.js
\n

Crie o arquivo de configuração do prettier prettier.config.js

\n
module.exports = {\n  semi: false,\n  singleQuote: true,\n  arrowParens: 'avoid',\n  trailingComma: 'none',\n  endOfLine: 'auto'\n}
\n

Crie o arquivo de configuração babel.config.js

\n
module.exports = {\n  presets: ['next/babel'],\n  plugins: [['styled-components', { ssr: true }]]\n}
\n

Instale o editorconfig

\n

Instale no seu vscode a extenção editorconfig, e na raiz do seu projeto crie com o botão direito o arquivo de configuração: Generate .editorconfig

\n
root = true\n\n[*]\nindent_style = space\nindent_size = 2\ncharset = utf-8\nend_of_line = lf\ntrim_trailing_whitespace = true\ninsert_final_newline = true
\n

Vamos ao styled-components

\n

Faça a instalação do styled-components e das tipagens

\n
yarn add styled-components\nyarn add @types/styled-components -D
\n

Crie um arquivo dentro da pasta pages chamado _document.tsx, com o seguinte conteúdo:

\n
import React from 'react'\nimport Document, {\n  DocumentInitialProps,\n  DocumentContext,\n  Html,\n  Head,\n  Main,\n  NextScript\n} from 'next/document'\nimport { ServerStyleSheet } from 'styled-components'\n\nexport default class MyDocument extends Document {\n  static async getInitialProps(\n    ctx: DocumentContext\n  ): Promise<DocumentInitialProps> {\n    const sheet = new ServerStyleSheet()\n    const originalRenderPage = ctx.renderPage\n\n    try {\n      ctx.renderPage = () =>\n        originalRenderPage({\n          enhanceApp: App => props => sheet.collectStyles(<App {...props} />)\n        })\n\n      const initialProps = await Document.getInitialProps(ctx)\n      return {\n        ...initialProps,\n        styles: (\n          <>\n            {initialProps.styles}\n            {sheet.getStyleElement()}\n          </>\n        )\n      }\n    } finally {\n      sheet.seal()\n    }\n  }\n\n  render(): JSX.Element {\n    return (\n      <Html lang="pt">\n        <Head>\n          <meta charSet="utf-8" />\n        </Head>\n        <body>\n          <Main />\n          <NextScript />\n        </body>\n      </Html>\n    )\n  }\n}
\n

Agora crie o arquivo de estilos globais da aplicação dentro da pasta styles: styles/global.ts

\n
import { createGlobalStyle } from 'styled-components'\n\nexport default createGlobalStyle`\n  *{\n    margin: 0;\n    padding: 0;\n    box-sizing: border-box;\n  }\n`
\n

Crie o arquivo de tema: styles/theme.ts

\n
const theme = {\n  colors: {\n    background: '#18191a',\n    text: '#e3e3e3',\n    primary: '#ed2a4c'\n  }\n}\n\nexport default theme
\n

Crie o arquivo de que define os tipos do tema: styles/styled.d.ts

\n
/* eslint @typescript-eslint/no-empty-interface: "off" */\nimport 'styled-components'\n\nimport theme from './theme'\n\nexport type Theme = typeof theme\n\ndeclare module 'styled-components' {\n  export interface DefaultTheme extends Theme {}\n}
\n

Importe o ThemeProvider do styled-components no _app.tsx

\n
[...]\nimport { ThemeProvider } from 'styled-components'\n\nimport GlobalStyle from '../styles/global'\nimport theme from '../styles/theme'\n\nreturn (\n    <ThemeProvider theme={theme}>\n      [...]\n\n      <GlobalStyle />\n    </ThemeProvider>\n)\n\n[...]
\n

As variaveis globais já estarão disponíveis para uso no arquivo styles/global.ts e deverá ser utilizada conforme a seguir:

\n
import { createGlobalStyle } from 'styled-components'\n\nexport default createGlobalStyle`\n  * {\n    margin: 0;\n    padding: 0;\n    box-sizing: border-box;\n  }\n\n  body {\n    background: ${props => props.theme.colors.background};\n    color: ${props => props.theme.colors.text};\n    font: 400 16px Roboto, sans-serif;\n  }\n\n  a {\n    color: ${props => props.theme.colors.background};\n    text-decoration: none;\n  }\n`
\n

Pronto! Tudo configurado para ser usado! Até mais.

\n

Código no GitHub

\n

Clique aqui para acessar todo o código no GitHub.

\n"},"__N_SSG":true}