DEV Community

A.J. Romaniello
A.J. Romaniello

Posted on • Updated on

A Full-Stack Application

GitHub logo aj-rom / hike-it-up-v2

The second coming of hike-it-up a React.js trail social media application.

I recently have completed a full-stack (backend and frontend) application, hike-it-up, and wanted to share how I went about creating this application and hosting it for completely free.

Some Background

I am finishing my time at The Flatiron School and wanted to showcase my new learnings by re-creating a very simple Sinatra application that I made earlier this year. Now that I had all this great knowledge of React I could combine it with my knowledge of Ruby on Rails to create a full-stack application.

Getting Things Started

Right off the bat, with experience from previous projects, I wanted my backend and frontend within the same GitHub repository. Both for ease of local deployment and because at the end we want to have 3 branches. One for our backend, one for our frontend, and one to house everything.

I initially started and used the create-react-app toolchain to generate my GitHub repository and frontend services.

After moving into the newly generated folder, I created a new rails API application named backend.

Now I had a folder for my backend, a public folder for my entry point, and a src folder for React related files.

Choosing Frameworks

I went with Pico.CSS for the framework, as it is a very lightweight CSS pack and has useful 'classless' styling properties.

Read more on Pico.CSS

I also wanted to have application state as well as client side routing. To achieve this I had to install some npm packages.
For application state I used redux with redux-thunk middleware.

For client side routing, I decided to go with react-router. This allowed me to mimick route browsing of the backend on the frontend. For example, going to /trails/1, should bring up the first trail. React Router passes the declarative id of the route, in this case /trails/:id, to the props of the route.

This allows us to make backend server calls ONLY when necessary, and doesn't break if someone were to link to it like this.

Building Out the Backend

I created resources for trails, users, and a model for addresses. Full CRUD operations should be able to be performed on trails, but only limited functionality should be able to be used for users.

To ensure malformed or malicious attempts would not be able to work, I built out a simple token authentication system that would verify the user for ever session. If they have the incorrect token, requests to the backend server will not be implemented.

Also, because I was separating where the frontend and backend servers are hosted, I needed to configure CORS. This would ensure requests where only valid if they came from my frontend's location.

After creating all pertinent relations and migrations I had my backend system up and running.

Frontend Challenges

When I was building out the frontend there were a couple of issues that I ran into, mostly because I was hosting this on gh-pages.

Switching To Hash Router

React Router has a nifty component called , which allows our UI to rely on the hash portion of the URL (www.example.com/#/I/Am/The-Hash-Portion).

This was necessary because I was hosting this application on a subdirectory of my GitHub domain. For example this application is hosted at https://aj-rom.github.io/hike-it-up-v2/ not https://aj-rom.github.io/. As normal routing would break this.

Persisting Application State

I had everything working as I wanted it except one thing, my state wouldn't persist on refresh. This made sense as there was nothing keeping application state stored in the users browser.

There were a couple of ways to implement this:

  1. Use redux-persist & redux-storage
  2. Persist application using raw JavaScript (build it myself)

After doing some research I learned that implementing this really wouldn't be difficult at all and this will save me two packages and maybe even more.

JavaScript has a nifty object accessible on every window, window.localStorage, that allows us to store data within the users page. This even persists when the page session ends, perfect for handling refreshes.

I went ahead and modified my application store, to continuously save to storage when it updated and then clear when the user logs out, clears their history, or deletes their account.

Hosting

Hosting the application is a whole different process, but luckily I have had some experience doing this in the past and have got a decent understanding on how to do this.

The Backend

For my backend I wanted to host it on Heroku which allows for simple deployment from GitHub repositories and is completely free.

Their deployment process is quite simple, all you have to do is link to a GitHub repository and choose a branch, then deploy the application.

To make my Heroku server as least crowded as possible, I created a new branch named heroku that would only contain the contents from the backend folder.

Now that I had this branch only containing Rails related files, I headed over to Heroku and deployed the application.

The Frontend

This is probably the easiest way to host a react application for completely free, especially if it lives in a GitHub repository.

The gh-pages npm package, makes for quick and easy deployment of fully compiled react applications.

After running two simple commands npm run predeploy && npm run deploy, the frontend was up and running!

Conclusion

I am very happy with the final outcome for this project as it pushed the limits of my understanding of JavaScript, Rails, HTTP protocol, and full-stack development.

All in all there are really only slight optimizations to be made using code splitting, and maybe implementing search functionality (which is pretty much done).

I hope this can be a resource for others to learn from or get inspiration for their next project!

Thanks for reading, if you would like to check out the application you can do so at this link, or if you would like to see the GitHub repository you can do so here.

Discussion (0)