<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: GLD5000</title>
    <description>The latest articles on DEV Community by GLD5000 (@gld5000).</description>
    <link>https://dev.to/gld5000</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F890370%2F65b53c7f-bff3-4d3a-8a25-2cf8372337bc.png</url>
      <title>DEV Community: GLD5000</title>
      <link>https://dev.to/gld5000</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gld5000"/>
    <language>en</language>
    <item>
      <title>Add stripe to a Next 13.4 App</title>
      <dc:creator>GLD5000</dc:creator>
      <pubDate>Tue, 15 Aug 2023 17:41:09 +0000</pubDate>
      <link>https://dev.to/gld5000/add-stripe-to-a-next-134-app-4mmc</link>
      <guid>https://dev.to/gld5000/add-stripe-to-a-next-134-app-4mmc</guid>
      <description>&lt;h3&gt;
  
  
  This is a guide to make a &lt;a href="https://nextjs.org/"&gt;Next.js&lt;/a&gt; project with &lt;a href="https://support.stripe.com/topics/getting-started"&gt;Stripe Payment GateWay&lt;/a&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  TLDR: &lt;a href="https://github.com/GLD5000/GLD-StripeTemplate"&gt;grab the template here&lt;/a&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Also including:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html"&gt;TypeScript&lt;/a&gt; for type safety&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://tailwindcss.com/docs/installation"&gt;Tailwind CSS&lt;/a&gt; for styling&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://jestjs.io/docs/getting-started"&gt;Jest&lt;/a&gt; for testing&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://eslint.org/docs/latest/use/getting-started"&gt;ESLint&lt;/a&gt; for linting&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://prettier.io/docs/en/install.html"&gt;Prettier&lt;/a&gt; for formatting&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://typicode.github.io/husky/getting-started.html"&gt;Husky&lt;/a&gt; &amp;amp; &lt;a href="https://github.com/okonet/lint-staged"&gt;Lint-Staged&lt;/a&gt; for pre-commit testing and linting&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  If you like this, checkout my other projects on &lt;a href="https://github.com/GLD5000"&gt;GitHub&lt;/a&gt; or via my &lt;a href="https://gld-portfolio.vercel.app/"&gt;Portfolio&lt;/a&gt;
&lt;/h3&gt;

&lt;h2&gt;
  
  
  Setup Stripe with Next 13.4
&lt;/h2&gt;

&lt;p&gt;To set up or better understand the project you can read on!&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Start with a clean Next.js install or my &lt;a href="https://github.com/GLD5000/GLD-NextTemplate"&gt;GLD-NextTemplate&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;If starting with the &lt;a href="https://github.com/GLD5000/GLD-NextTemplate"&gt;GLD-NextTemplate&lt;/a&gt;, run &lt;code&gt;npm i&lt;/code&gt; to set up dependencies etc.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;npm i stripe axios&lt;/code&gt; to install stripe and axios (You can also just use the native Fetch API if you like).&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Setup Account on Stripe
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="https://stripe.com/"&gt;Stripe&lt;/a&gt; and setup an account with your email address (You do not need a credit card or anything as you can just stay in 'test mode').&lt;/li&gt;
&lt;li&gt;Copy your secret key from the 'Developers' Tab and put it into a '.env' file in your repos root directory.&lt;/li&gt;
&lt;li&gt;Add some products using the 'Products' tab (we will use the API to fetch these for our page).&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Create API route handlers
&lt;/h3&gt;

&lt;p&gt;You will need two handlers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;To fetch products from your Stripe account&lt;/li&gt;
&lt;li&gt;To enable checkout for a desired product&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  api/getproducts/route.ts:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Stripe from 'stripe';
import { NextResponse } from 'next/server';

/* eslint-disable import/prefer-default-export */

export async function GET() {
    if (process.env.STRIPE_SECRET_KEY) {
        const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
            apiVersion: '2022-11-15',
        });
        const products = await stripe.products.list({
            limit: 4,
            expand: ['data.default_price'],
        });
        // console.log('products:', products)
        return NextResponse.json(products.data);
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  api/checkout/route.ts:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Stripe from 'stripe';
import { NextResponse, NextRequest } from 'next/server';

/* eslint-disable import/prefer-default-export */

export async function POST(request: NextRequest) {
    if (process.env.STRIPE_SECRET_KEY) {
        const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
            apiVersion: '2022-11-15',
        });
        const data = await request.json();
        const { priceId } = data;
        const session = await stripe.checkout.sessions.create({
            line_items: [
                {
                    price: priceId,
                    quantity: 1,
                },
            ],
            mode: 'payment',
            success_url: `${process.env.HOST_URL}`,
            cancel_url: `${process.env.HOST_URL}`,
        });

        return NextResponse.json(session.url);
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Integrate getproducts (AKA fetch) API route
&lt;/h3&gt;

&lt;h4&gt;
  
  
  The fetch is be enabled by a useEffect on page / site load:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    useEffect(() =&amp;gt; {
        fetchProducts();
    }, []);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  The fetchProducts function gets an array of products and sets the component state to the result:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    async function fetchProducts() {
        const { data } = await axios.get('/api/getproducts');
        setProducts(data);
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  We map over the returned array, sending each product to a product card:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    function getProductCards(productData: Product[]) {
        return productData.map((data) =&amp;gt; (
            &amp;lt;ProductCard key={data.id} data={data} /&amp;gt;
        ));
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Then we return the product card array to the page:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   return (
        &amp;lt;div className="grid sm:grid-cols-2 gap-16"&amp;gt;
            {getProductCards(products)}
        &amp;lt;/div&amp;gt;
    );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  I put these parts together in a 'ProductCards.tsx':
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'use client';

import axios from 'axios';
import { useState, useEffect } from 'react';
import { Product } from '@/lib/stripe/types';
import ProductCard from './ProductCard';

export default function ProductCards() {
    const [products, setProducts] = useState([]);

    useEffect(() =&amp;gt; {
        fetchProducts();
    }, []);

    return (
        &amp;lt;div className="grid sm:grid-cols-2 gap-16"&amp;gt;
            {getProductCards(products)}
        &amp;lt;/div&amp;gt;
    );

    async function fetchProducts() {
        const { data } = await axios.get('/api/getproducts');
        setProducts(data);
    }

    function getProductCards(productData: Product[]) {
        return productData.map((data) =&amp;gt; (
            &amp;lt;ProductCard key={data.id} data={data} /&amp;gt;
        ));
    }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Integrate the checkout API Route
&lt;/h3&gt;

&lt;h4&gt;
  
  
  In the product card, there is a button for buying a product:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  &amp;lt;Button onClick={handleClickBuy}&amp;gt;Buy Now&amp;lt;/Button&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  This button has a click handler which makes the API request and gives control of the window location to the Stripe checkout returned:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    async function handleClickBuy(e: SyntheticEvent) {
        e.preventDefault();
        const { data: checkout } = await axios.post(
            '/api/checkout',
            {
                priceId: id,
            },
            {
                headers: {
                    'Content-Type': 'application/json',
                },
            }
        );
        window.location.assign(checkout);
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  I put these in a ProductCard.tsx component:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Image from 'next/image';
import axios from 'axios';
import { SyntheticEvent } from 'react';
import { Price, Product } from '@/lib/stripe/types';
import { Button } from '../ui/button';

export default function ProductCard({ data }: { data: Product }) {
    const {
        name,
        description,
        images: [image],
        default_price: price,
    } = data;
    const { currency, unit_amount: amount, id } = price as Price;
    if (!name || !description || !image) return null;
    return (
        &amp;lt;div className="grid gap-4 border rounded shadow p-6 lg:max-w-[35rem]"&amp;gt;
            &amp;lt;Image
                priority
                src={image}
                alt={description}
                width={806}
                height={671}
            /&amp;gt;
            &amp;lt;h2 className="text-6xl font-bold mx-auto w-fit"&amp;gt;{name}&amp;lt;/h2&amp;gt;
            &amp;lt;p className="mx-auto"&amp;gt;{description}&amp;lt;/p&amp;gt;
            &amp;lt;b className="mx-auto"&amp;gt;{`${
                amount ? amount * 0.01 : 'N/A'
            } ${currency}`}&amp;lt;/b&amp;gt;
            &amp;lt;Button onClick={handleClickBuy}&amp;gt;Buy Now&amp;lt;/Button&amp;gt;
        &amp;lt;/div&amp;gt;
    );

    async function handleClickBuy(e: SyntheticEvent) {
        e.preventDefault();
        const { data: checkout } = await axios.post(
            '/api/checkout',
            {
                priceId: id,
            },
            {
                headers: {
                    'Content-Type': 'application/json',
                },
            }
        );
        window.location.assign(checkout);
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  On Types
&lt;/h3&gt;

&lt;h4&gt;
  
  
  I also decided to destructure the type definitions for 'Product' and 'Price' and export them from my own module so I did not need to keep importing the stripe module and using dot notation to access them (lib/stripe/types.ts):
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Stripe from 'stripe';

export type Product = Stripe.Product;
export type Price = Stripe.Price;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's about it- remember to like / star if you found this useful!&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>stripe</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Next.js 13.4 &amp; Jest &amp; Cypress Setup Guide</title>
      <dc:creator>GLD5000</dc:creator>
      <pubDate>Sun, 06 Aug 2023 22:47:33 +0000</pubDate>
      <link>https://dev.to/gld5000/nextjs-134-basics-how-i-set-up-a-project-51a7</link>
      <guid>https://dev.to/gld5000/nextjs-134-basics-how-i-set-up-a-project-51a7</guid>
      <description>&lt;h2&gt;
  
  
  Getting Started with Next 13.4
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How I set up a project
&lt;/h3&gt;

&lt;h4&gt;
  
  
  This is a step-by-step guide to make a &lt;a href="https://nextjs.org/"&gt;Next.js&lt;/a&gt; project with:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html"&gt;TypeScript&lt;/a&gt; for type safety&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://tailwindcss.com/docs/installation"&gt;Tailwind CSS&lt;/a&gt; for styling&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://jestjs.io/docs/getting-started"&gt;Jest&lt;/a&gt; for testing components etc.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.cypress.io/guides/getting-started/installing-cypress"&gt;Cypress&lt;/a&gt; for end to end testing etc.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://eslint.org/docs/latest/use/getting-started"&gt;ESLint&lt;/a&gt; for linting&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://prettier.io/docs/en/install.html"&gt;Prettier&lt;/a&gt; for formatting&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://typicode.github.io/husky/getting-started.html"&gt;Husky&lt;/a&gt; &amp;amp; &lt;a href="https://github.com/okonet/lint-staged"&gt;Lint-Staged&lt;/a&gt; for pre-commit testing and linting&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  If you like this, checkout my other projects on &lt;a href="https://github.com/GLD5000"&gt;GitHub&lt;/a&gt; or via my &lt;a href="https://gld-portfolio.vercel.app/"&gt;Portfolio&lt;/a&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  You can also read this guide on &lt;a href="https://gld-dev-blog.vercel.app/blogpost/clky99brt0000mi0851uxf2dm"&gt;my blog&lt;/a&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;h4&gt;
  
  
  TLDR: This setup is available as a template in my &lt;a href="https://github.com/GLD5000"&gt;GitHub Account&lt;/a&gt; if you want the quickest path to the end result or want to see the setup in context- &lt;a href="https://github.com/GLD5000/GLD-NextTemplate"&gt;GLD-NextTemplate&lt;/a&gt;
&lt;/h4&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Installation and Repo setup
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;npx create-next-app@latest&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;code my-app&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git init&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gh repo create&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git add .&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git commit . -m "Initial Commit"&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git push -u origin main&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Setup Testing
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Jest
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Install Jest, ts-jest, jsdom, testing libraries &amp;amp; eslint plugins: &lt;code&gt;npm i -D jest ts-jest jest-environment-jsdom @testing-library/jest-dom @testing-library/react eslint-plugin-jest-dom eslint-plugin-testing-library&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add jest.config.mjs
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import nextJest from "next/jest.js";

const createJestConfig = nextJest({
  // Provide the path to your Next.js app to load next.config.js and .env files in your test environment
  dir: "./",
});

// Add any custom config to be passed to Jest
/** @type {import('jest').Config} */
const config = {
  // Add more setup options before each test is run
  setupFilesAfterEnv: ["&amp;lt;rootDir&amp;gt;/jest.setup.js"],

  testEnvironment: "jest-environment-jsdom",
};

// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
export default createJestConfig(config);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Add jest.setup.js:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import '@testing-library/jest-dom/extend-expect'
import React from 'react'

function MockImage(props) {
    return React.createElement('img', props)
}
jest.mock('next/image', () =&amp;gt; MockImage)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Add scripts to package.json:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  "scripts": {
    "test": "clear &amp;amp;&amp;amp; jest",
    "test:noClear": "jest",
    "test:watch": "clear &amp;amp;&amp;amp; jest --watchAll",
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Add first test in &lt;code&gt;\_\_tests\_\_/home.test.tsx&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import { render } from '@testing-library/react';
import Home from '@/app/page';

describe('Home component', () =&amp;gt; {
  it('renders correctly', () =&amp;gt; {
    render(&amp;lt;Home /&amp;gt;);

    const heroHeading = screen.getByTestId('hero-heading');
    expect(heroHeading).toBeInTheDocument();

    const madeByText = screen.getByText(/Made by GLD5000/i);
    expect(madeByText).toBeInTheDocument();

  });
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Cypress
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Install latest Cypress: &lt;code&gt;npm i -D cypress@latest&lt;/code&gt; (currently "cypress": "^12.17.3" at time of writing)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Start a dev server in a terminal: &lt;code&gt;npm run dev&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open Cypress from a second terminal: &lt;code&gt;npx cypress open&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once open, click 'E2E Testing' button to configure and then click 'continue' (if you get an error relating to 'bundle' you may need to switch tsconfig.json &lt;code&gt;"moduleResolution": "bundler",&lt;/code&gt; to &lt;code&gt;"moduleResolution": "node",&lt;/code&gt;), when prompted for a browser choose e.g. Chrome and click to add scaffolded examples if you like.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Setup new config files &lt;strong&gt;within the 'cypress' folder&lt;/strong&gt;:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  cypress/eslintrc.json with disabled rules to accommodate cypress example specs:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "plugins": ["cypress"],
    "extends": ["plugin:cypress/recommended"],
    "rules": {
        "testing-library/await-async-utils": "off",
        "no-unused-expressions": "off",
        "@typescript-eslint/ban-ts-comment": "off",
        "cypress/unsafe-to-chain-command": "off",
        "@typescript-eslint/no-unused-vars": "off",
        "@typescript-eslint/no-empty-function": "off",
        "func-names": "off",
        "@typescript-eslint/no-var-requires": "off",
        "global-require": "off",
        "testing-library/no-debugging-utils": "off",
        "no-param-reassign": "off"
    },
    "overrides": [
        {
            "files": ["viewport.cy.js", "waiting.cy.js"],
            "rules": {
                "cypress/no-unnecessary-waiting": "off"
            }
        }
    ]
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  cypress/tsconfig.json:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "compilerOptions": {
        "target": "es5",
        "lib": ["es5", "dom", "dom.iterable", "esnext"],
        "allowJs": true,
        "skipLibCheck": true,
        "strict": true,
        "forceConsistentCasingInFileNames": true,
        "noEmit": true,
        "esModuleInterop": true,
        "module": "esnext",
        "moduleResolution": "node",
        "resolveJsonModule": true,
        "isolatedModules": true,
        "jsx": "preserve",
        "incremental": true,
        "plugins": [
            {
                "name": "next"
            }
        ],
        "paths": {
            "@/*": ["./src/*"]
        }
    },
    "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
    "exclude": ["node_modules"]
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Update exclude and include in root tsconfig.json:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts","cypress/tsconfig.json"],
    "exclude": ["node_modules", "./cypress.config.ts","cypress"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Put an eslint disable comment in the cypress.config.ts:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* eslint-disable */
import { defineConfig } from "cypress";

export default defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      // implement node event listeners here
    },
  },
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Add script to package.json:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  "scripts": {
    ...
   "cypress": "npx cypress open"
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Add first test:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;  Add &lt;code&gt;data-testid&lt;/code&gt; attribute to H1 on app/page.tsx:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;lt;h1 data-testid="hero-heading" className="w-fit mx-auto text-5xl font-bold text-center"&amp;gt;
                Minimal Starter Template for
            &amp;lt;/h1&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  Add test in cypress/e2e/home.cy.ts:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;describe("template spec", () =&amp;gt; {
  it("H1 contains correct text", () =&amp;gt; {
    cy.visit("http://localhost:3000/");
    cy.get("[data-testid='hero-heading']").contains("Minimal Starter Template for");
  });
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setup Linting
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Install prettier: npm i -D prettier eslint-plugin-prettier eslint-config-prettier&lt;/li&gt;
&lt;li&gt;Make prettier config e.g.: &lt;code&gt;touch .prettierrc.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Configure prettier e.g.:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default {
    trailingComma: "es5",
    tabWidth: 4,
    semi: false,
    singleQuote: true,
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Setup eslint: &lt;code&gt;npm init @eslint/config&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Install Eslint AirBnb: &lt;code&gt;npm i -D eslint-config-airbnb&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Get peer dependency list for AirBnb config: list peer dependencies &lt;code&gt;npm info "eslint-config-airbnb@latest"&lt;/code&gt; e.g.:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   eslint: '^7.32.0 || ^8.2.0',
  'eslint-plugin-import': '^2.25.3',
  'eslint-plugin-jsx-a11y': '^6.5.1',
  'eslint-plugin-react': '^7.28.0',
  'eslint-plugin-react-hooks': '^4.3.0'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Paste into package.json devDependencies and watch for conflicts (duplicates) you will not need &lt;code&gt;eslint&lt;/code&gt; if it is already installed with Next.js.&lt;/li&gt;
&lt;li&gt;Run npm install to install the extra dependencies: &lt;code&gt;npm i&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Install Eslint typescript: &lt;code&gt;npm i -D @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-config-airbnb-typescript&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Install testing plugins: &lt;code&gt;npm i -D eslint-plugin-jest-dom eslint-plugin-testing-library&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Update eslint config e.g.:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
    extends: [
        'next/core-web-vitals',
        'plugin:testing-library/react',
        'plugin:jest-dom/recommended',
        'airbnb',
        'prettier',
        'eslint:recommended',
        'plugin:react/recommended',
        'plugin:react/jsx-runtime',
        'plugin:@typescript-eslint/recommended',
    ],
    plugins: ['prettier', 'react'],
    ignorePatterns: ['*.ttf', '*.css'],
    rules: {
        '@next/next/no-img-element': 'off',
        'import/no-extraneous-dependencies': 'off',
        'react/require-default-props': 'off',
        'react/jsx-props-no-spreading': 'off',
        'react/jsx-no-useless-fragment': 'off',
        'no-undef': 'off',
        'import/extensions': 'off',
        'react/jsx-uses-react': 'error',
        'react/jsx-uses-vars': 'error',
        'no-console': 'off',
        'react/jsx-no-bind': 'off',
        'react/prop-types': 'off',
        'no-use-before-define': ['error', { functions: false }],
        'react/jsx-filename-extension': 'off',
        'prettier/prettier': ['error'],
        'jsx-a11y/label-has-associated-control': [
            2,
            {
                controlComponents: [
                    'InputSelect',
                    'SectionTitle',
                    'InputTitle',
                    'InputText',
                ],
                depth: 3,
            },
        ],
    },
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setup Linting Pre Hooks
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;npm i -D husky&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;npm pkg set scripts.prepare="husky install"&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;npm i&lt;/code&gt; or &lt;code&gt;npm run prepare&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;npm install -D lint-staged&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Add hook: &lt;code&gt;npx husky add .husky/pre-commit "npx lint-staged"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Make lint-staged configuration file:&lt;code&gt;touch lint-staged.config.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add lint-staged configuration e.g.:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
    // this will check Typescript files
    '**/*.(ts|tsx)': () =&amp;gt; 'yarn tsc --noEmit',

    // This will format and lint TS &amp;amp; JS Files
    '**/*.(ts|tsx|js)': (filenames) =&amp;gt; [
        `yarn prettier --write ${filenames.join(' ')}`,
        `yarn eslint --fix --max-warnings=0 ${filenames.join(' ')}`,
    ],

    // this will Format MarkDown and JSON
    '**/*.(md|json)': (filenames) =&amp;gt;
        `yarn prettier --write ${filenames.join(' ')}`,
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Add optional testing hook e.g.: &lt;code&gt;npx husky add .husky/pre-commit "npm run test:noClear"&lt;/code&gt; so your pre-commit file could look something like this:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm run test:noClear
npx lint-staged

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setup Additional Scripts
&lt;/h2&gt;

&lt;p&gt;Package.json:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    "lint": "clear &amp;amp;&amp;amp; next lint",
    "test": "clear &amp;amp;&amp;amp; jest",
    "test:noClear": "jest",
    "test:watch": "clear &amp;amp;&amp;amp; jest --watchAll",
    "test:v": "clear &amp;amp;&amp;amp; jest --verbose",
    "format": "clear &amp;amp;&amp;amp; prettier \"src/**/*.{js,jsx,ts,tsx,css,scss}\" --write",
    "lint:fix": "clear &amp;amp;&amp;amp; prettier \"src/**/*.{js,jsx,ts,tsx,css,scss}\" --write &amp;amp;&amp;amp; eslint src --ext .js,.jsx,.ts,.tsx --fix",
    "lint:all": "clear &amp;amp;&amp;amp; prettier \"src/**/*.{js,jsx,ts,tsx,css,scss}\" --write &amp;amp;&amp;amp; eslint src --ext .js,.jsx,.ts,.tsx --fix &amp;amp;&amp;amp; tsc --noEmit"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  That's It!
&lt;/h2&gt;

&lt;p&gt;Not exactly a short process but this will give a really useful base to build quality code with. Don't forget to like / star if you found this useful! If you like, you can also check out my other &lt;a href="https://github.com/GLD5000"&gt;projects&lt;/a&gt; and &lt;a href="https://dev.to/gld5000"&gt;blogs&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>cli</category>
      <category>beginners</category>
      <category>react</category>
    </item>
    <item>
      <title>Agile Basics</title>
      <dc:creator>GLD5000</dc:creator>
      <pubDate>Mon, 24 Jul 2023 21:15:35 +0000</pubDate>
      <link>https://dev.to/gld5000/agile-basics-36a9</link>
      <guid>https://dev.to/gld5000/agile-basics-36a9</guid>
      <description>&lt;h2&gt;
  
  
  Agile vs Waterfall
&lt;/h2&gt;

&lt;p&gt;Two common types of project management are Agile and Waterfall and a good way to understand Agile is to compare it to Waterfall. &lt;/p&gt;

&lt;h3&gt;
  
  
  Waterfall
&lt;/h3&gt;

&lt;p&gt;The simplest way to explain Waterfall is as a sequence (or sequence of sequences). Tasks are planned and carried out in order. &lt;/p&gt;

&lt;p&gt;This works best where there is a defined end goal and firm requirements for your project. It also means that a client may not see the fruits of your labour until close to or at the end when it is all finished. &lt;/p&gt;

&lt;p&gt;You will produce what you were told to in the first instance but also your client will have no chance to change their minds along the way. &lt;/p&gt;

&lt;p&gt;A good example of this style of project would be building a house. You will have set expectations and immovable regulations you need to adhere to and when changes occur they will be mainly led by unforeseen issues emanating from the project itself e.g. underground obstacles or variations affecting foundations. &lt;/p&gt;

&lt;p&gt;You cannot build the roof before the foundations etc. so things will need to be done in a strict sequential order.&lt;/p&gt;

&lt;h3&gt;
  
  
  Agile
&lt;/h3&gt;

&lt;p&gt;Agile is different. Agile was created for software where the rules about ordering tasks can be more flexible. You can, for example, build a facade or user interface for a product that does not work yet. It may lack foundations but it will be able to look the part and give a client a good idea of what the end product may look like. &lt;/p&gt;

&lt;p&gt;In software, your wire-framing and initial design could look exactly like your end product if you wish so there is no problem of a client saying: "I thought it would look bigger in real life" because both the plans and the end product exist in the same space.&lt;/p&gt;

&lt;p&gt;This flexibility also means that you can show your client an unfinished product or part of a product and get feedback throughout the process. Any problems you have from the client are better to have earlier in the process - this called &lt;strong&gt;Failing Fast&lt;/strong&gt; i.e. not storing up trouble for later but getting the bad news first so you can avoid wasted efforts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agile Values
&lt;/h2&gt;

&lt;p&gt;These are comparative values which state that whilst the traditional project values are still important, these should take precedence. These can be seen as revolving around central tenets of the utmost importance of customer service and the effective application of efforts. Responding to and meeting (or exceeding) the needs of the customer is the top priority and feeds into all aspects of the project and methods of working. The Agile methodology seeks to extract the most value from a team and project and minimise wasted efforts through continuous delivery and feedback from the customer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Individuals and interactions
&lt;/h3&gt;

&lt;h4&gt;
  
  
  over processes and tools
&lt;/h4&gt;

&lt;p&gt;Processes and tooling should be a response to communicated needs. Working methods should fit the brief and most recent feedback whilst also accommodating the individuals in the team and utilising their skills in the most effective way.&lt;/p&gt;

&lt;h3&gt;
  
  
  Working software
&lt;/h3&gt;

&lt;h4&gt;
  
  
  over comprehensive documentation
&lt;/h4&gt;

&lt;p&gt;Getting software in front of your customer is more important than writing documentation. A meeting and demonstration of a working product is more valuable than a delayed product with good documentation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Customer collaboration
&lt;/h3&gt;

&lt;h4&gt;
  
  
  over contract negotiation
&lt;/h4&gt;

&lt;p&gt;Agile works by involving the customer throughout the process, including changes of needs and expectations along the way. This should be a collaborative process where expertise is shared in both directions to arrive at the best outcome.&lt;/p&gt;

&lt;p&gt;As a result, the full pathway is not clear in the initial stages and having an overly restrictive contract will only result in a sub-optimal product based on flawed initial predictions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Responding to change
&lt;/h3&gt;

&lt;h4&gt;
  
  
  over following a plan
&lt;/h4&gt;

&lt;p&gt;The reason for short sprints / iterations of production is to allow for change. Products change and expand over time. This could be a customer led change, or a change in technology etc. A good project should be able to leverage any external changes to improve the project outcome. &lt;/p&gt;

&lt;p&gt;Also, the less time spent on an unnecessary feature, the better it will be for productivity and morale.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Twelve Principles
&lt;/h2&gt;

&lt;p&gt;These are derived from the values above and are fairly self-explanatory. They can be further grouped into four areas:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Value Delivery
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Our highest priority is to &lt;strong&gt;satisfy the customer&lt;/strong&gt; through &lt;strong&gt;early and continuous delivery&lt;/strong&gt;
of valuable software.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deliver working software frequently&lt;/strong&gt;, from a couple of weeks to a couple of months, with a preference to the shorter timescale.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Working software&lt;/strong&gt; is the primary measure of progress.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simplicity&lt;/strong&gt;--the art of maximising the amount of work not done--is essential.&lt;/li&gt;
&lt;li&gt;Continuous attention to &lt;strong&gt;technical excellence&lt;/strong&gt; and &lt;strong&gt;good design&lt;/strong&gt; enhances agility.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Business Collaboration
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Welcome changing requirements&lt;/strong&gt;, even late in development. Agile processes harness change for the customer's competitive advantage.&lt;/li&gt;
&lt;li&gt;Business people and developers must &lt;strong&gt;work together daily&lt;/strong&gt; throughout the project.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Team Dynamics and Culture
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Build projects around motivated individuals&lt;/strong&gt;. Give them the environment and support they need, and trust them to get the job done.&lt;/li&gt;
&lt;li&gt;The most efficient and effective method of conveying information to and within a development team is &lt;strong&gt;face-to-face conversation&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Agile processes promote &lt;strong&gt;sustainable development&lt;/strong&gt;. The sponsors, developers, and users should be able to maintain a &lt;strong&gt;constant pace&lt;/strong&gt; indefinitely.&lt;/li&gt;
&lt;li&gt;The best architectures, requirements, and designs emerge from &lt;strong&gt;self-organising teams&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Retrospectives and Continuous Learning
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;At regular intervals, the team &lt;strong&gt;reflects&lt;/strong&gt; on how to become more effective, then tunes and &lt;strong&gt;adjusts&lt;/strong&gt; its behaviour accordingly.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>agile</category>
      <category>beginners</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Git &amp; GitHub Basics: Useful CLI Patterns</title>
      <dc:creator>GLD5000</dc:creator>
      <pubDate>Mon, 24 Jul 2023 20:57:55 +0000</pubDate>
      <link>https://dev.to/gld5000/git-github-basics-useful-cli-patterns-1op4</link>
      <guid>https://dev.to/gld5000/git-github-basics-useful-cli-patterns-1op4</guid>
      <description>&lt;p&gt;&lt;strong&gt;TLDR: You can skip to the bottom of the article for cheatsheets of the terminology and the commands I used with all their meanings.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This blog will be more of a reference to common patterns I use on the Command Line Interface (CLI). I use Git CLI and GitHub CLI so if you see &lt;strong&gt;gh&lt;/strong&gt; instead of &lt;strong&gt;git&lt;/strong&gt; that means it is a GitHub command.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing GitHub CLI
&lt;/h2&gt;

&lt;p&gt;I would recommend &lt;a href="https://github.com/cli/cli#installation"&gt;installing the GitHub CLI&lt;/a&gt; which you can do on Linux as follows (sorry it is long):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type -p curl &amp;gt;/dev/null || (sudo apt update &amp;amp;&amp;amp; sudo apt install curl -y)
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
&amp;amp;&amp;amp; sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \
&amp;amp;&amp;amp; echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list &amp;gt; /dev/null \
&amp;amp;&amp;amp; sudo apt update \
&amp;amp;&amp;amp; sudo apt install gh -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apparently, this script makes sure that curl is available, downloads a GitHub CLI archive keyring, sets the necessary permissions, adds the GitHub CLI repository configuration, updates package lists, and then installs the GitHub CLI package -simple!&lt;/p&gt;

&lt;p&gt;Once you have that installed, you may not need to use it often but it will offer real quality of life improvements when interacting with GitHub. Find out more &lt;a href="https://docs.github.com/en/github-cli/github-cli"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now that we have that sorted, let's get into some common use cases and patterns you might find useful!&lt;/p&gt;

&lt;h2&gt;
  
  
  Starting from a Local Repository
&lt;/h2&gt;

&lt;p&gt;If you are using a getting started guide or tutorial, there is a good chance you might be starting on your local machine from scratch using something like &lt;a href="https://nextjs.org/docs/getting-started/installation"&gt;create-next-app&lt;/a&gt; or &lt;a href="https://vitejs.dev/guide/#scaffolding-your-first-vite-project"&gt;create vite&lt;/a&gt; (both excellent options in my opinion).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Use your create command e.g. &lt;code&gt;npx create-next-app@latest new-app&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Launch a VSCode window for the new directory e.g. &lt;code&gt;code new-app&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Initialise the repository using git: &lt;code&gt;git init&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Create the repository on GitHub:
Once you have completed these steps, you will have a Git repo on your local machine but you will most likely want to hook it up to GitHub which you can do using the GitHub CLI. If it is your first time using the CLI you will need to login:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh auth login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are already logged in, you can create a remote copy of you git repository on GitHub using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh repo create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will then be given series of prompts to interact with, for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;? &lt;strong&gt;What would you like to do?&lt;/strong&gt; Push an existing local repository to GitHub&lt;/li&gt;
&lt;li&gt;? &lt;strong&gt;Path to local repository&lt;/strong&gt; .&lt;/li&gt;
&lt;li&gt;? &lt;strong&gt;Repository name&lt;/strong&gt; my-app&lt;/li&gt;
&lt;li&gt;? &lt;strong&gt;Description&lt;/strong&gt; testing&lt;/li&gt;
&lt;li&gt;? &lt;strong&gt;Visibility&lt;/strong&gt; Public&lt;/li&gt;
&lt;li&gt;✓ &lt;strong&gt;Created repository&lt;/strong&gt; USERNAME/my-app &lt;strong&gt;on GitHub&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;? &lt;strong&gt;Add a remote?&lt;/strong&gt; Yes&lt;/li&gt;
&lt;li&gt;? &lt;strong&gt;What should the new remote be called?&lt;/strong&gt; origin&lt;/li&gt;
&lt;li&gt;✓ &lt;strong&gt;Added remote&lt;/strong&gt; &lt;code&gt;https://github.com/USERNAME/my-app.git&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;N.B. The dot &lt;code&gt;.&lt;/code&gt; for &lt;strong&gt;Path to local repository&lt;/strong&gt; means &lt;strong&gt;use current directory&lt;/strong&gt;- assuming you are in the directory of the repo you wish to add to GitHub.&lt;/p&gt;

&lt;p&gt;I really like this method because it is very ergonomic and gives you confidence that you are doing what you intended to do, with helpful confirmations each time it performs an action on your GitHub account.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;After you have setup your local repo and create a remote on GitHub, it is time for your first commit:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git add .
git commit . -m "Initial Commit"
git push -u origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above commands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add / Stage all files to be committed&lt;/li&gt;
&lt;li&gt;Commit all the files&lt;/li&gt;
&lt;li&gt;Push the commit and setup a link between the main branch on the local repo and the same on the remote (GitHub)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You should only need to set the upstream branch once and then subsequent pushes can be done simply using &lt;code&gt;git push&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Starting from a Remote Repository
&lt;/h2&gt;

&lt;p&gt;If you are not starting a project locally, you are probably starting remotely. This could mean that you just &lt;a href="https://docs.github.com/en/get-started/quickstart/fork-a-repo"&gt;forked a repo&lt;/a&gt; on GitHub or you just &lt;a href="https://docs.github.com/en/get-started/quickstart/create-a-repo?tool=webui"&gt;created a repo&lt;/a&gt; on GitHub using their guided process.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to the &lt;strong&gt;Code&lt;/strong&gt; section of your repo and find the &lt;strong&gt;GitHub CLI&lt;/strong&gt; command:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh repo clone USERNAME/my-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Enter that into your terminal and then use &lt;code&gt;code my-app&lt;/code&gt; to open it in VSCode.&lt;/li&gt;
&lt;li&gt;Once in the repo and in VSCode you will want to use &lt;code&gt;npm i&lt;/code&gt; to install any dependencies. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;N.B. If your project is using &lt;a href="https://typicode.github.io/husky/getting-started.html"&gt;Husky&lt;/a&gt; you may need to add &lt;code&gt;npx husky install&lt;/code&gt; to enable the hooks.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Once you have made some sort of change, you can push to the remote using:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git commit . -m "My Message"
git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Resuming Work on a Shared Repository
&lt;/h2&gt;

&lt;p&gt;If you are going back to work on a shared repository with no local changes it is a good idea to pull any changes from the remote before you get going so you make sure you are working starting with the latest version of the repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git pull
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Start Working on a Feature Branch
&lt;/h2&gt;

&lt;p&gt;Once you have your local and remote repo working together in harmony, you may want to muddy the waters by creating a new branch or feature branch. &lt;/p&gt;

&lt;p&gt;One benefit of having a feature branch is that you can experiment without taking down your running application, usually deployed from your main branch. &lt;/p&gt;

&lt;p&gt;Another benefit is that, if you do not have push access for the main branch, you can make a feature branch and push to that to your hearts' delight and before making a pull request on GitHub to have the feature branch merged in.&lt;/p&gt;

&lt;p&gt;To create a branch called &lt;code&gt;new-feature&lt;/code&gt; and start working on it, you can use one of the following methods:&lt;/p&gt;

&lt;h3&gt;
  
  
  Copy branch to a new branch and then switch to it
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git branch -c new-feature
git switch new-feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create and checkout a new branch
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout -b new-feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create and switch to a new branch
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git switch -c new-feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basically, the &lt;code&gt;-c&lt;/code&gt; flag is for &lt;strong&gt;copy&lt;/strong&gt; or &lt;strong&gt;create&lt;/strong&gt; and the &lt;code&gt;-b&lt;/code&gt; flag is for &lt;strong&gt;branch&lt;/strong&gt; but the effects of all these commands are eerily similar. &lt;strong&gt;You will end up in your new branch within your editor.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, you will want to push your newly created branch to a corresponding branch on the remote (GitHub). Again, there is more than one way to do this:&lt;/p&gt;

&lt;h3&gt;
  
  
  By naming the branch
&lt;/h3&gt;

&lt;p&gt;This works with or without the -u (set upstream) flag&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git push -u origin new-feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;-u&lt;/code&gt; flag is useful if you want to make further pushes after using &lt;code&gt;git push&lt;/code&gt; as it will set up tracking for you.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git push origin new-feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Using the currently checked out branch (HEAD)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git push origin HEAD
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Finish Working on a Feature Branch
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Create a Pull Request
&lt;/h3&gt;

&lt;p&gt;After you have finished your feature you can go to GitHub and create a pull request or you can use &lt;strong&gt;GitHub CLI&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gh pr create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will give you some prompts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;? &lt;strong&gt;Title&lt;/strong&gt; My First Pull Request&lt;/li&gt;
&lt;li&gt;? &lt;strong&gt;Body&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;? &lt;strong&gt;What's next?&lt;/strong&gt; Submit&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Delete the branch
&lt;/h3&gt;

&lt;p&gt;Deleting branches can be dangerous so always be sure. Luckily, git will stop you from deleting the branch you are on, so if you switch to the main branch, you will not be able to accidentally delete it. To delete branch &lt;code&gt;new-feature&lt;/code&gt; from the local machine and GitHub (origin) do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git switch main
git branch -d new-feature
git push origin -d new-feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These commands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Switch to the main branch&lt;/li&gt;
&lt;li&gt;Delete the local copy of the &lt;code&gt;new-feature&lt;/code&gt; branch&lt;/li&gt;
&lt;li&gt;Delete the origin (or remote) copy of the &lt;code&gt;new-feature&lt;/code&gt; branch using the &lt;code&gt;-d&lt;/code&gt; delete flag&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;N.B. You can also delete upstream branches using a &lt;code&gt;:&lt;/code&gt; colon prefix e.g.:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git push origin :new-feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  CheatSheets
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Git Terms
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;repo / repository&lt;/strong&gt; - Git / Code Directory&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;branch&lt;/strong&gt; - Copy of a Repository that can be independently worked on&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HEAD&lt;/strong&gt; - Current Working Branch&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;origin&lt;/strong&gt; - Remote repository e.g. GitHub&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;commit&lt;/strong&gt; - A saved version of a Git that includes a message and information about what changed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ref&lt;/strong&gt; - A file containing commit information&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pull request&lt;/strong&gt; - Ask someone to pull changes from your branch into another branch e.g. main&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Git Actions
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;checkout&lt;/strong&gt; - Start working on a branch&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;switch&lt;/strong&gt; - Switch to a different branch&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pull&lt;/strong&gt; - Pull any changes from one branch or place (e.g. Remote / Local) to another&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;push&lt;/strong&gt; - Push your changes to another place or branch&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;add&lt;/strong&gt; - Add a file to the observed files so Git can track its changes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;commit&lt;/strong&gt; - Add file changes to a new commit that can be pushed to a branch&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Commands
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;gh auth login&lt;/code&gt; - Login to GitHub&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gh repo create&lt;/code&gt; - Create a new remote repo on GitHub&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gh repo clone USERNAME/my-app&lt;/code&gt; - Create a local clone of the 'my-app' repo from GitHub&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gh pr create&lt;/code&gt; - Create a pull request for the current branch&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git add .&lt;/code&gt; - Add all files for Git tracking&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git commit . -m "Initial Commit"&lt;/code&gt; - Commit All files with a message of "Initial Commit"&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git push -u origin main&lt;/code&gt; - Set upstream for 'main' branch to same named branch on origin (GitHub)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git push&lt;/code&gt; - Push the current branch to origin (GitHub)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git pull&lt;/code&gt; - Fetch any changes for the current repo and branch from origin (GitHub)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git branch -c new-feature&lt;/code&gt; - Copy current branch to a new branch called 'new-feature'&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git switch new-feature&lt;/code&gt; - Switch to branch called 'new-feature'&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git checkout -b new-feature&lt;/code&gt; - Create and checkout a new branch called 'new-feature'&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git switch -c new-feature&lt;/code&gt; - Create and switch to a new branch called 'new-feature'&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git push origin new-feature&lt;/code&gt; - Push 'new-feature' branch to origin and create if not present&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git push origin HEAD&lt;/code&gt; - Push current (HEAD) branch to origin and create if not present&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git branch -d new-feature&lt;/code&gt; - Delete the 'new-feature' branch locally&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git push origin -d new-feature&lt;/code&gt; - Delete the 'new-feature' branch on remote / origin / GitHub&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git push origin :new-feature&lt;/code&gt; - Delete the 'new-feature' branch on remote / origin / GitHub&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cli</category>
      <category>github</category>
      <category>git</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
