Building a multilingual website for booking tourist activities
For a client, I designed and developed a multilingual website for booking tourist activities
using Gatsby.js with React and SASS on the frontend and Express.js on the backend.
I learned how to take a website from initial idea, to being launched and serving customers.
Note:The website's content hasn't yet been translated into other languages,
so unfortunately it is not possible to test the support for multiple languages yourself at this time.
I was approached by a client who wanted to create a website offering various
activities for tourists in Prague.
After working together to concretize the idea and the client's requirements, we went through
a few iterations to find a suitable design.
I then built the website using React, Gatsby.js and SCSS on the frontend and Node.js with Express.js on the backend.
After the website was built, I took care of its deployment and occasional maintenance.
Later, I also made a few smaller improvements, such as adding the ability to filter activities by category.
Some interesting parts of the project were making sure that the layout of the website was responsive and mobile-friendly,
implementing support for multiple languages (although this functionality isn't currently in use because the content hasn't been translated yet),
and building a booking form whose input fields can be individually configured for each activity.
The result
The result of this project is a live website that is being used by real customers to book activities.
You can take a look at the finished website for yourself. At the moment there
is only English content on the site and translated content remains to be added, so unfortunately it's not
possible to try out the support for multiple languages.
My approach
Analyzing requirements
After working with the client to clarify their ideas and needs for the website, we identified the following main requirements:
The site should support multiple languages to better accommodate tourists from different countries.
The design should be simple and focus on showcasing the activities.
The website should be fast to load and mobile friendly.
It should be easy to expand the functionality of the website in the future. For example, it should be possible
to add a payment gateway in the future to allow customers to make payments directly on the website.
Updates to the website's content won't be very frequent.
With these requirements in mind, there were two possible approaches to building the site:
either use an existing website builder or develop a custom website. Unfortunately, the number
of website builders that had built-in support for localization and the possibility of
adding online payments in the future was very limited, and none of them fully met the client's expectations,
so in the end we decided to go the route of a simple custom website.
This solution also allows to customize the booking forms exactly to one's needs and
generally allows for more control over the look and functionality of the site.
We also agreed that it wouldn't be worth it to make the website editable
by the client for the time being, because content updates would be infrequent and it wouldn't be worth the cost and time to build
a full admin interface or integrate an existing CMS.
The design process
After clarifying the overall organization of the website and the structure of its individual pages,
I made a few mockups of possible design directions.
The client wanted the website to have a simple and minimalist appearance (he cited the look of Pinterest as an example)
and wanted the main focus to be on the activities themselves.
Through several iterations, we arrived at a clean and minimalist design that prominently
features images to help users visualize what it is like to participate in the offered activities.
The activity details page also includes different types of media as part of the description, such
as images, videos, maps, and more.
Part of the design was also the creation of a simple logo that fits well with the website's design,
with variations for different applications, such as the website's favicon.
Building the website
For the frontend of the website I decided to use React in combination with Gatsby.js because I was
quite familiar with React and the site had no dynamic content, so it could be statically generated.
The backend runs on Node.js and uses Express.js to serve the frontend and provide an API for submitting the contact and booking forms.
Using JavaScript on both the frontend and the backend made it possible to share parts of the code between them,
for example by reusing the same logic for both client-side and server-side validation.
An interesting part of this project was building in support for multiple languages (although it isn't currently in use because
the client hasn't provided translated content yet).
Support for localization required hooking into Gatsby's content loading system to add metadata about the content language
and generate localized page URLs,
extending the built-in routing system to support localized URLs, implementing a system for translating text that is part
of the website's layout, and more.
Since the booking and contact form is arguably the most important part of the site,
I made sure to give it some extra care. This included user-friendly input validation,
making the submit button react to the current form submission state,
and saving unsubmitted form data to localStorage (so the user doesn't lose their progress if the page is accidentally reloaded or closed).
The booking forms for each activity are configurable and allow adding different input fields
for each activity. The forms also include basic spam reduction measures:
a honeypot input and a control question, which are automatically hidden if the user's web browser has
JavaScript enabled. So far, this strategy has worked surprisingly well to keep out spam bots
while not bothering users with additional work.
Deployment and maintenance
Once the website was built, there were a few more things to do.
To deploy the website, I had to set up the domain and web hosting (I went with Roští.cz, which provides SSH access to a container
running NGINX and Node.js). A new task for me was to properly set up everything around sending emails,
so that they are trustworthy and don't get rejected as spam (for anyone who has done this before,
terms like SPF, DKIM or DMARC are probably familiar).
Once the website was up and running, I took care of occasionally updating the content, updating some dependencies,
and making further smaller improvements, such as adding the ability to filter activities by category.
What I learned
Thanks to this project, I had the opportunity to go through all the phases of building a website,
from the client's initial idea, through requirements analysis, design and development, up to deployment and maintenance.
In hindsight, I probably could have saved myself some work and brought even more value to the client by
taking a more active role in the early stages of the project. Although I was hired
primarily as a designer and developer, I should have started by helping to define
a clear business plan and high-level goals for the project before gathering
specific requirements for the website's design and functionality.
While building the website, I learned a lot about internationalization and localization,
including how to properly spell "internationalization" and how to implement localized routing and linking.
Even though Gatsby.js didn't support localization out of the box, I came to appreciate its very
customizable and flexible API, which allowed me to hook into almost any part of the framework and adapt it to the needs of the project.
This project also helped me realize how quickly some JavaScript frameworks and libraries change.
Among other things, I had to go through a major version upgrade of Gatsby.js in the middle of developing the website.
My takeaway is to always consider whether a dependency is really necessary and adds enough
value to the project to be worth it.
Last but not least, I also learned a thing or two about building responsive websites, as evidenced by the fact
that I can already see some things I would do differently next time.