Continued setup of a nextjs typescript installation.
setup.sh
is the shell script to run to set up the rest of the installation and pull in the files bundled in this gist.
Continued setup of a nextjs typescript installation.
setup.sh
is the shell script to run to set up the rest of the installation and pull in the files bundled in this gist.
{ | |
"presets": ["next/babel"], | |
"plugins": ["babel-plugin-styled-components"] | |
} |
{ | |
"extends": ["next", "next/core-web-vitals", "airbnb-typescript", "prettier"], | |
"parserOptions": { | |
"project": "./tsconfig.json" | |
} | |
} |
{ | |
"semi": true, | |
"trailingComma": "es5", | |
"singleQuote": true, | |
"tabWidth": 2, | |
"useTabs": false | |
} |
import { ThemeProvider } from "styled-components"; | |
import { theme } from "../styles/theme"; | |
import GlobalStyle from "../styles/global"; | |
import type { AppProps } from 'next/app' | |
function MyApp({ Component, pageProps }: AppProps) { | |
return ( | |
<ThemeProvider theme={theme}> | |
<GlobalStyle /> | |
<Component {...pageProps} /> | |
</ThemeProvider> | |
) | |
} | |
export default MyApp |
import Document, { Html, Head, Main, NextScript, DocumentContext, DocumentInitialProps } from "next/document"; | |
class MyDocument extends Document { | |
// ?Next docs indicate this is an old function? | |
static async getInitialProps(ctx: DocumentContext): Promise<DocumentInitialProps> { | |
const initialProps: DocumentInitialProps = await Document.getInitialProps(ctx); | |
return { ...initialProps }; | |
} | |
render() { | |
return ( | |
<Html lang="en"> | |
<Head> | |
<link rel="icon" href="/favicon-32x32.png" /> | |
{/* <link rel="preconnect" href="https://fonts.gstatic.com" /> */} | |
{/* <link href="https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;500;700&display=swap" rel="stylesheet" /> */} | |
</Head> | |
<body> | |
<Main /> | |
<NextScript /> | |
</body> | |
</Html> | |
); | |
} | |
} | |
export default MyDocument; |
import { createGlobalStyle, css } from "styled-components"; | |
const GlobalStyle = createGlobalStyle` | |
${({ theme }) => { | |
const { colors } = theme; | |
return css` | |
/* BEGIN RESET */ | |
/* Box sizing rules */ | |
*, | |
*::before, | |
*::after { | |
box-sizing: border-box; | |
} | |
/* Remove default padding */ | |
ul[class], | |
ol[class] { | |
padding: 0; | |
} | |
/* Remove default margin */ | |
body, | |
h1, | |
h2, | |
h3, | |
h4, | |
h5, | |
p, | |
ul[class], | |
ol[class], | |
li, | |
figure, | |
figcaption, | |
blockquote, | |
dl, | |
dd { | |
margin: 0; | |
} | |
/* Set core body defaults */ | |
body { | |
scroll-behavior: smooth; | |
text-rendering: optimizeSpeed; | |
line-height: 1.6; | |
} | |
/* Remove list styles on ul, ol elements with a class attribute */ | |
ul[class], | |
ol[class] { | |
list-style: none; | |
} | |
/* A elements that don't have a class get default styles */ | |
a:not([class]) { | |
text-decoration-skip-ink: auto; | |
} | |
/* Make images easier to work with */ | |
img { | |
max-width: 100%; | |
display: block; | |
} | |
/* Natural flow and rhythm in articles by default */ | |
article > * + * { | |
margin-top: 1em; | |
} | |
/* Inherit fonts for inputs and buttons */ | |
input, | |
button, | |
textarea, | |
select { | |
font: inherit; | |
} | |
/* Remove all animations and transitions for people that prefer not to see them */ | |
@media (prefers-reduced-motion: reduce) { | |
* { | |
animation-duration: 0.01ms !important; | |
animation-iteration-count: 1 !important; | |
transition-duration: 0.01ms !important; | |
scroll-behavior: auto !important; | |
} | |
} | |
/* END RESET */ | |
html, | |
body { | |
font-family: sans-serif; | |
/* add font size */ | |
height: 100%; | |
margin: 0; | |
padding: 0; | |
} | |
#__next { | |
height: 100%; | |
} | |
.App { | |
height: 100%; | |
} | |
main { | |
height: 100%; | |
} | |
`; | |
}} | |
`; | |
export default GlobalStyle; |
import Head from 'next/head' | |
export default function Home() { | |
return ( | |
<div className="App"> | |
<Head> | |
<title></title> | |
<meta name="description" content="" /> | |
</Head> | |
<main> | |
<h1>Hello World</h1> | |
</main> | |
<footer> | |
Created by ____ | |
</footer> | |
</div> | |
) | |
} |
#!/bin/bash | |
# Bash script to automate the rest of my nextjs typescript set up after creating a new repo. | |
# Should be run in the base of a newly generated nextjs project with typescript | |
# run `chmod +x setup.sh` to make executable | |
# I'd rather create two arrays. 1 for normal dependencies and 1 for dev. | |
# loop through those with the appropriate commands. | |
# npm packages add any npm packages you want to install to the appropriate arrays | |
packages=("styled-components" "@types/styled-components") | |
devPackages=( | |
"babel-plugin-styled-components" | |
"eslint-plugin-import" | |
"@typescript-eslint/eslint-plugin" | |
"@typescript-eslint/parser" | |
"eslint-config-airbnb-typescript" | |
"eslint-plugin-jsx-a11y" | |
"eslint-plugin-react" | |
"eslint-plugin-react-hooks" | |
) | |
echo "Installing npm packages." | |
for p in ${packages[@]}; do | |
npm install $p | |
done | |
for dp in ${devPackages[@]}; do | |
npm install --save-dev $dp | |
done | |
# array of file paths to delete | |
delFiles=( | |
"./styles/Home.module.css" | |
"./styles/globals.css" | |
"./public/favicon.ico" | |
"./public/vercel.svg" | |
"./pages/api/hello.ts" | |
) | |
echo "Deleting unneeded files." | |
for file in ${delFiles[@]}; do | |
rm -f $file | |
done | |
# array of directories to create | |
folders=("@types" "src") | |
echo "Creating needed directories" | |
for f in ${folders[@]}; do | |
mkdir $f | |
done | |
# 2 arrays. 1 for the file paths we will write to. 1 for urls we will read. | |
# They should be of the same length. They will be connected by index. | |
writePaths=( | |
"./.babelrc" | |
"./pages/_document.tsx" | |
"./styles/theme.ts" | |
"./styles/global.ts" | |
"./pages/_app.tsx" | |
"./@types/styled.d.ts" | |
"./pages/index.tsx" | |
"./.eslintrc" | |
) | |
readUrls=( | |
"https://gist.githubusercontent.com/rv-rmcgavin/7ec4e5b3dcc0dbda30c343e5fcfdff3f/raw/5f1d7dfe915286baecc78397332a74f5116b72a2/.babelrc" | |
"https://gist.githubusercontent.com/rv-rmcgavin/7ec4e5b3dcc0dbda30c343e5fcfdff3f/raw/524e8b864a42b4ac257cbd5ff1ab640e5c3c54af/_document.tsx" | |
"https://gist.githubusercontent.com/rv-rmcgavin/7ec4e5b3dcc0dbda30c343e5fcfdff3f/raw/41e1fef5a02eea57b0af54aad33845fed599bbdf/theme.ts" | |
"https://gist.githubusercontent.com/rv-rmcgavin/7ec4e5b3dcc0dbda30c343e5fcfdff3f/raw/de3cf9fdc2b31139eb6777420dd9c918f7140850/global.ts" | |
"https://gist.githubusercontent.com/rv-rmcgavin/7ec4e5b3dcc0dbda30c343e5fcfdff3f/raw/838e47f49a833515a94555e6c4f07eac17e2c52b/_app.tsx" | |
"https://gist.githubusercontent.com/rv-rmcgavin/7ec4e5b3dcc0dbda30c343e5fcfdff3f/raw/c369dd7414015b8c6ce86a62403b9e58a3a9c776/styled.d.ts" | |
"https://gist.githubusercontent.com/rv-rmcgavin/7ec4e5b3dcc0dbda30c343e5fcfdff3f/raw/724b7fbf01b61db8a131b3d28a773bccc150988e/index.tsx" | |
"https://gist.githubusercontent.com/rickMcGavin/6698c9413a3cfb4969c560d2269dfe9c/raw/30274ab74136c5aa35978fb786b4c089f3b43142/.eslintrc.json" | |
"https://gist.githubusercontent.com/rickMcGavin/6698c9413a3cfb4969c560d2269dfe9c/raw/30274ab74136c5aa35978fb786b4c089f3b43142/.prettierrc.json" | |
) | |
echo "Downloading and saving files from gists" | |
for i in ${!writePaths[@]}; do | |
wget -O ${writePaths[$i]} ${readUrls[$i]} | |
done |
// import original module declarations | |
import 'styled-components'; | |
interface Neutral { | |
500: string; | |
} | |
interface Colors { | |
primary: string; | |
neutral: Neutral; | |
white: string; | |
} | |
// and extend them! | |
declare module 'styled-components' { | |
export interface DefaultTheme { | |
colors: Colors; | |
breakpoint: string; | |
} | |
} |
import { DefaultTheme } from 'styled-components'; | |
export const theme: DefaultTheme = { | |
colors: { | |
primary: 'hsl(172, 67%, 45%)', // strong cyan | |
neutral: { | |
500: 'hsl(184, 14%, 56%)', | |
}, | |
white: 'hsl(0, 0%, 100%)', | |
}, | |
breakpoint: `(min-width: 900px)` | |
}; |