"Create an account, log in, search for, and leave reviews for your favorite books!"
-
PERN Stack:
- PostgreSQL
- Express.js
- React
- Node.js
- JavaScript
- Local Storage, Session Storage
- GoodReads API
- Deployed to Heroku
- Redux
- React Router
- React Bootstrap
- SCSS
- Axios
- Converted from originally Python, Flask, Jinja2 project
- CRUD capabilities - users can GET, POST, PUT, DELETE their own comment reviews of individual books
- Users can log in to search for books, leave reviews, edit and delete their reviews, and see average reviews and review counts per book from Goodreads API data.
- Express.js server-side fetch of Goodreads API endpoints as well as database queries using PostgreSQL for books, user reviews, and user login information.
- Books imported from a CSV file of 5000 books
- Environment variables stored via Heroku
After deploying the production version to Heroku, when refreshing or GET requesting the 'details' page of any book (/details/9958 route for example), I was stuck with a plain, white screen with only a JSON object of the API response data for that book. My Express.js routes were catching all of the GET requests before React could load the index.html page, therefore the application had no webpage to display the API data onto.
I wanted my HTML to be pre-rendered in order for the fetched GoodReads API and database data to successfully "hydrate" and display on the page.
To remedy this, I found a work-around on my server-side using the Express.js res.sendFile(path, options)
method to pre-render
the template index.html file as the path
argument, along with the API response data object in the options
argument.
// detailsRouter.js
let options = {
headers: {
'result': (results from GoodReads API fetch),
'comment_list': (comments from the database fetch),
'bookinfo': (book info from the database fetch)
}
}
res.sendFile(path.join(__dirname, "../client/build/index.html"), options);
Before finally deploying the application on Heroku for production, I installed the Heroku Postgres add-on to host the
PostgreSQL database for my users, books, and reviews. I made sure to include the DATABASE_URL
environment variable
provided by Heroku to link to the app's process.env
and used conditional boolean logic to select either "deployment" or "production"
mode configuration.
This ensured the application was using either the "development mode" local database, or the "production mode" heroku hosted database.
{`// db.js
const devConfig = {
user: process.env.PG_USER,
host: process.env.PG_HOST,
database: process.env.PG_DATABASE,
password: process.env.PG_PASSWORD,
port: process.env.PG_PORT
}
const prodConfig = {
connectionString: process.env.DATABASE_URL // <-- heroku add-on Postgres database URL
}
const pool = new Pool(process.env.NODE_ENV === "production" ? prodConfig : devConfig)
`}