Next JS Boot Script

By Eric David Smith on March, 15 2020 10:30 AM ~ 4 min read

Hi friends. I've got a quick tip for you today.

Problem

When you begin a new software project, it's often an exciting time. However, time is money and time spent setting up boilerplate code and configuring development environments can be a real pain in the neck for event the most seasoned developers.

Solution

One of the things I like to do as a self proclaimed "lazy programmer" is create bash scripts to help me kick off a bunch of projects so my teams can focus on the "meat and potatoes" - or the "fruit and veggies" so to speak... the product.

So, if you like using NextJS or if you've never written a line of code before, try this little trick out some time.

#!/usr/bin/env bash
# Author: Eric David Smith @ Colorful Dots, LLC :: erictherobot@gmail.com
# Usage:
# chmod -x next-boot.sh
# source ./next-boot.sh <app name here>
# License: MIT / OSS - Use however you intend. Just don't blame me if something breaks.

printf "\x$(printf %x)
 _     _  ______  _     _  _______  ______   _____
(_)   (_)(______)( )   ( )(__ _ __)(______) (_____)
(__)_ (_)(_)__    (_)_(_)    (_)        (_)(_)___
(_)(_)(_)(____)    (___)     (_)    _   (_)  (___)_
(_)  (__)(_)____  (_) (_)    (_)   ( )__(_)  ____(_)
(_)   (_)(______)(_)   (_)   (_)    (____)  (_____)
                                                    "
echo "Creating Next.js Project: $1 ..."
mkdir $1
cd $1
mkdir pages
mkdir -p pages/static
mkdir -p components/Meta
mkdir -p components/Header
mkdir -p components/Footer
mkdir -p components/Layouts
mkdir -p public/static
echo "Created directories pages, components, public/static"

cat <<'EOF' > package.json
{
  "name": "next-js-boot-script",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "dev": "next | json-server --watch db.json --port 3004"
  },
  "dependencies": {
    "isomorphic-unfetch": "*",
    "json-server": "*",
    "next": "*",
    "next-mdx-enhanced": "*",
    "react": "*",
    "react-dom": "*"
  }
}
EOF

yarn

cat <<'EOF' > db.json
{
  "posts": [
    {
      "id": 1,
      "title": "This is the title",
      "author": "eric",
      "date": "02-28-2020"
    },
    {
      "id": 2,
      "title": "This is another title",
      "author": "eric",
      "date": "02-27-2020"
    }
  ],
  "comments": [{ "id": 1, "body": "some comment", "postId": 1 }],
  "profile": { "name": "eric" }
}
EOF

echo "
const Index = props => (
  <main>
    <h1>NextJS + MDX</h1>
  </main>
)
export default Index
" > pages/index.js

echo "function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}
export default MyApp
" > pages/_app.js

echo "export const Header = () => {
  return <div>Header</div>
}
" > components/Header/Header.js

echo "export const Footer = () => {
  return <div>Footer</div>
}
" > components/Footer/Footer.js

echo "import Head from 'next/head'
export const Meta = props => {
  return (
    <Head>
      <title>{props.title}</title>
    </Head>
  )
}
" > components/Meta/Meta.js

echo "import { Header, Footer, Meta } from '../index'
export default ({ children, title, description }) => (
  <div>
    <Meta title={title} description={'some desc'} />
    <Header />
    <main>{children}</main>
    <Footer />
  </div>
)
" > components/Layouts/main-layout.js

echo "import { Header, Footer, Meta } from '../index'
export default frontMatter => {
  return ({ children: content }) => {
    return (
      <div>
        <Meta title={frontMatter.title} description={'some desc'} />
        {frontMatter.hasHeader ? <Header /> : null }
        <main>{content}</main>
        <Footer />
      </div>
    )
  }
}
" > components/Layouts/mdx-layout.js

echo "
---
layout: 'mdx-layout'
title: 'Introduction'
description: 'This is a description'
heading: 'This is a heading'
hasSidebar: true
hasHeader: true
hasFooter: true
---
Here's some _markdown_ content!
" > pages/static/index.mdx

echo "import Document, { Html, Head, Main, NextScript } from 'next/document'
class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx)
    return { ...initialProps }
  }
  render() {
    return (
      <Html>
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}
export default MyDocument
" > pages/_document.js

echo "
function App({ Component, pageProps }) {
  return <Component {...pageProps} />
}
export default App
" > pages/_app.js

echo "export * from './Meta/Meta'
export * from './Header/Header'
export * from './Footer/Footer'
" > components/index.js

echo "
node_modules
.mdx-data
" > .gitignore

echo "const withMdxEnhanced = require('next-mdx-enhanced')
module.exports = withMdxEnhanced({
  layoutPath: 'components/Layouts',
  defaultLayout: true,
  fileExtensions: ['mdx', 'md'],
  remarkPlugins: [],
  rehypePlugins: [],
  extendFrontMatter: {
    process: (mdxContent, frontMatter) => {},
    phase: 'both',
  },
})(/* your normal nextjs config */)
" > next.config.js

echo "Hello World" > README.md

echo "Completed install!"

git init

yarn dev

open http://localhost:3000

Installation

  • Copy the code above.

  • Paste into a text file and name the file extension next-boot.sh (or something else)

  • Make the script executable by running this next command in your Terminal of choice.

    chmod -x next-boot.sh

  • Then run:

    source ./next-boot.sh <app name here>

  • Happy coding!


Eric David Smith

Father / Entrepreneur / Student / Teacher / Software Engineer / Recording Artist / Navy Veteran / Runner / Ambivert