Pernecom is a simplified ecommerce website built with the PERN (PostgreSQL, Express, React, Node) stack. It includes front-end routing (React Router), authentication (Passport.js), and checkout/payment integration (Stripe Checkout).
Take a look: https://ecommerce-pern-app-z9pn.onrender.com/.
Product listing pages are dynamically rendered based on the URL path (homepage, category, or search results), using JSON data fetched from back-end API endpoints.
Relevant code: front-end products components; products API endpoints; categories API endpoints; database query functions.
Product detail pages are dynamically rendered based on the product ID in the URL path, using JSON data fetched from a back-end API endpoint.
Content is dynamically rendered depending on authentication status (log in or add to cart button) and available stock count (no stock message, low stock message, or out of stock message).
Relevant code: front-end products components; products API endpoints; database query functions.
Authentication is implemented using Passport.js and Express session middleware, including both local login and Sign In With Google. In the case of local login, passwords are hashed and verified using node.bcrypt.js.
A visitor's authentication status is used to dynamically render and/or restrict access to content and functionality across both the back end and front end:
- Relevant API endpoints return a 401 status code if the user is not authenticated (logged out) or not authorised (trying to access another user's data), resulting in a user-friendly error message on the front end
- Primary navigation links change if the user is authenticated (account; cart; log out) or not (register; log in)
- The product detail page button changes if the user is authenticated (add to cart) or not (log in)
Relevant code: front-end authentication components; back-end authentication logic; authentication API endpoints; Passport.js and sessions configurations; database query functions.
Authenticated visitors can add items to their cart, remove items from in their cart, and check out. These actions modify database stock counts (actual and available) to prevent orders exceeding stock.
The checkout journey includes Stripe Checkout payment integration (in test mode). Several API calls are used to create a pending order, establish a payment session, and ultimately confirm the order. Database transactions are used where appropriate to ensure that changes (e.g. stock counts) are made only if all related queries are successful.
Relevant code: front-end cart & checkout components; cart API endpoints; checkout API endpoints; database query functions.
Authenticated visitors can view a summary of their previous orders (status; date; total cost) on the main account page, with extra details (order item summaries and delivery address) available via order detail pages.
Relevant code: front-end orders components; orders API endpoints; database query functions.
Front-end URL routing is implemented using React Router v6, utilising dynamic paths (params, e.g. category URL slugs and order IDs) and data retrieval functions (loaders) to fetch relevant JSON data from back-end API endpoints.
Relevant code: routing configuration; various React components (e.g. ProductFeed).
Comprehensive error handling is used throughout the back end and front end. Non-success API endpoint status codes are typically used to render a user-friendly message on the front end.
Relevant code: inline error page component; fallback error page component; virtually every other file!
The database structure is documented in a Database Markup Language file and visualised in a diagram.
The back-end API is documented using Swagger UI, available at http://localhost:8000/docs/ (refer to setup) or in JSON & YAML source files.
- PostgreSQL
- Node.js
- Express v4 (including several middleware modules)
- node-postgres
- Passport.js
- node.bcrypt.js
- Stripe Checkout
- dotenv
- Jest
- SuperTest
- React v18
- TypeScript v4
- React Router v6
- Stripe Checkout
- React Stripe.js
- React Testing Library
- React Icons
- Clone/download a local copy of this repository.
- Using the command line, navigate to the
/back-end
subdirectory and runnpm install
to install package dependencies (using thepackage-lock.json
file). - Create a PostgreSQL database, optionally using the SQL provided in
/back-end/db/db-creation.sql
, using a PostgreSQL client application (e.g. pgAdmin) or the command line (psql). - Create and populate the database tables using the SQL provided in
/back-end/db/table-creation.sql
and/back-end/db/table-population.sql
respectively. - In the
/back-end
subdirectory, rename theexample.env
file to.env
. - In the
.env
file, update the values corresponding to secrets, IDs, and the PostgreSQL database configuration as required. Refer to the following documentation for more details:- https://expressjs.com/en/resources/middleware/session.html#secret
- https://node-postgres.com/features/connecting#environment-variables
- https://www.postgresql.org/docs/current/libpq-envars.html
- https://www.passportjs.org/concepts/authentication/google/
- https://www.passportjs.org/tutorials/google/register/
- https://docs.stripe.com/keys
- Optional: using the command line, run
npm test
in the/back-end
subdirectory to run the test suite (all tests should pass if the steps above were successful). - Using the command line, run
node index.js
in the/back-end
subdirectory to start the API server. - Optional: navigate to http://localhost:8000/docs/ to view the back-end API Swagger UI documentation.
- Using a new command line window, navigate to the
/front-end
subdirectory and runnpm install
to install package dependencies (using thepackage-lock.json
file). - In the
/front-end
subdirectory, rename theexample.env
file to.env
. - In the
.env
file, update the Stripe public key value (https://docs.stripe.com/keys). - Using the command line, run
npm start
in the/front-end
subdirectory to start the React app (while the back-end API server is still running via a separate command line window). - The application should launch in your browser, but otherwise can be accessed at http://localhost:3000/.
Yes! A deployed version of the website can be found here: https://ecommerce-pern-app-z9pn.onrender.com/. (The checkout payment functionality is in test mode, so you won't be charged).
This is one of the practice projects that I completed as part of the Codecademy Full-Stack Engineer career path. Later, I used this project to practice implementing TypeScript (converted from the existing JavaScript).
I planned and built it almost entirely independently; only the key requirements (core functionality and technologies) and a few links to documentation were provided. Some aspects were definitely challenging, requiring a lot of reading through documentation and Stack Overflow!
In particular, I now have significantly more experience with:
- Database design and documentation
- API design and documentation
- Local and third-party authentication, using Passport.js and Express session configuration
- Checkout/payment functionality using Stripe and a lot of SQL
- Data loading using React Router v6
- TypeScript