Skip to content

My Ideal Map, a web app to allow users to save places with **external links** on Google Maps

License

Notifications You must be signed in to change notification settings

masakudamatsu/mima

Repository files navigation

My Ideal Map

A full-stack web app for those who love exploring cities to save places on the embedded Google Maps with links to external sites—a feature unavailable with Google Maps’s official app unless you use clunky Google My Maps.

Demo

my-ideal-map.mp4

URL

https://my-ideal-map.app

Accessing the above URL redirects you to a login page. Please follow the instruction there to log in to a demo account so that you can see how the app works.

It is hosted by Vercel, chosen for its seamless integration with a full-stack Next.js app.

How It’s Made

1. Integration of front-end and back-end

The app is built with Next.js so that I can seamlessly integrate code bases for the front-end UI (src/pages/) and for the back-end server (src/pages/api).

2. Embedded Google Maps

For a map, I rely on Google Maps, rather than map services based on OpenStreetMap (e.g., Mapbox), because I find its place search feature is the best. Place search is at the core of My Ideal Map because its main feature, saving a place of interest, cannot be done without searching a place.

Consequently, with Google Maps JavaScript API, the app embeds custom-styled Goole Maps fullscreen (src/components/Map.js).

Since I use Next.js, the actual implementation requires a little customization rather than simply following what the API documentation tells us to do. For detail, see my blog post “4 gotchas when setting up Google Maps API with Next.js and ESLint”.

3. Text editor

The app allows the user to save a place on the map along with a note that turns URLs into link text—a feature missing in Google Maps’s official app.

This feature is built with TipTap, a very-easy-to-use rich-text editor library that extends ProseMirror, combined with DOMPurify for security and Autolinker.js for detecting URL strings. See the following React components for how I implement it:

4. Dark mode after 6pm

Google Maps's official app does not automatically switch between light and dark modes. The map in light mode is glaring when the user is walking outside after dark. The map in dark mode is difficult to see under the sunlight. My Ideal Map aims to improve this aspect of user experience.

The app detects the user’s local time with JavaScript’s Date object (src/wrappers/NightModeContext.js).

Then if it’s between 6pm and 6am, the app applies a data-* attribute to the <body> element to render the UI in dark mode (src/hooks/useNightMode.js).

For detail on implementation, see my blog post “Switching embedded Google Maps into custom dark mode after 6pm”.

In the future, I plan to advance this feature by switching on the dark mode after the sunset in the user’s local area.

5. Autocomplete place search

It is a tough job to build autocomplete search from scratch with accessibility taken into account (see “Editable Compobox with List Autocomplete” in ARIA Authoring Practices Guide). Consequently, I rely on battle-tested Downshift.js. To customize the UI of the search box and autocomplete suggestions, I incorporate Google Maps Places API into Downshift.js.

See the following React components for how I implement it:

For more detail, see a trilogy of my blog posts on this topic:

6. User’s current location

The app utilizes Geolocation API so that the user can track their own location on the embedded Google Maps. The app also detects the direction of movement from two subsequent locations with a trigonometry formula.

See the following React components for how I implement it:

For more detail, see my blog post “Showing user’s direction of movement on embedded Google Maps”.

Optimizations

Dynamic import

To reduce the initial bundle size, I use Next.js’s next/dynamic module to lazy-load the React components for place search (Lines 18-27 in Search.js) and for editing notes on saved places (Lines 27-36 in SavedPlaces.js).

Avoid props in Styled Components

I use Styled Components for generating CSS stylesheets (src/elements/). It is now widely known that performance can suffer from the use of CSS-in-JS. Following the advice from Aggelos Arvanitakis in 2019, I avoid the use of props, which causes the rendering of additional components (i.e., React context consumers).

About

My Ideal Map, a web app to allow users to save places with **external links** on Google Maps

Topics

Resources

License

Stars

Watchers

Forks

Languages