Welcome to the MapLibre React Components tutorial! We'll be building a small, but feature-rich map app that will help you understand the fundamentals of this library.
For this tutorial, we'll be using Vite for our bundler / dev server .
You should be able to visit the URL of the vite server.
You should see the Vite start page.
It's time to do a big cleanup and delete all unnecessary files.
Modify your App.tsx
and index.css
to get the minimum to work.
You now have a clean base to start the tutorial.
Let's now add our first component RMap
which will internally instanciate a Map object from the maplibre-gl
library
In a few lines you have seen the first fundamental concept of the library.
The RMap
component is a wrapper of the Map
object from the maplibre-gl
library. It accepts as props all
options that can be passed to Map
as MapOptions
.
There is, however, a difference. React is a reactive library and therefore some of the props must be reactive. To
distinguish reactive props from non-reactive props, simply look if the prop is prefixed with initial
.
If this is the case, the prop will be used at instantiation but any modification of the prop subsequently will not cause it to be updated on our Map instance.
Note: There is one exception with the style
from MapOptions
who become the reactive mapStyle
prop for
the RMap
component. This avoids a conflict with the style
prop of RMap
which defines the style attribute
of the containing element div.maplibregl-map
.
By default our RMap
component takes all the space of its parent element; you could change this behavior
by updating the style
prop.
Your RMap
component accepts components as children
. These components has access to your map instance and
can automatically add controls
, layers
, sources
or marker
to your map.
As with the RMap
component, the RMarker
component accepts all options that can be passed to the Marker
object. Non-reactive props are prefixed with initial
.
Let's add an event handler and a hook to make our map a little more dynamic.
With this code you have just seen a new concept of the library. It is possible to listen to events associated
with your maplibre
objects (ex with map object map.on('<event-name>')
. Here you can pass handlers to your
events using props that have the name of your event and prefixed with "on". Your handler accepts a parameter
which is your native maplibre event.
You can add MapLibre's default controls by invoking its associated component.
All components accept control options as props as well as the position
prop allowing you to choose the
location of your control.
It's time to add a little facelift to your application...
In addition to the mapLibre native object wrappers, the library has some components that should delight you,
such as this RGradientMarker
component which has all the properties of RMarker
with some interesting extra props.
You can also import the modern
theme from the maplibre-theme
package. In addition to being 3 times
lighter than the default theme, it is compatible with dark mode and easily customizable with CSS variables.
RGradientMarker
can contain icon or text content. If you use any font icon kit (fontello, fontawesome,
etc...), just specify the className and it will be wrapped inside a <i className={icon} />
element.
Otherwise, you need to specify a factory function who generate your HTMLElement
or SVGSVGElement
.
RSource
/ RLayer
Now let's add 2 components that go together to display data on our map.
If you're using TypeScript
add the geojson
types with your package manager npm install -D @types/geojson
.
Note some important details, notably the presence of the key
prop.
When you have conditional renderers within your RMap
component you will need to set the prop key
for
your RSource
to help React maintain its association with the correct component.
Consider id
for maplibre
mapping and key
for React mapping. If maplibre-react-components
detects
a mapping error it will throw an exception.
Props of these components are reactive so don't forget to define your objects outside of your component to avoid performance issues.
Also note that the type
prop is read-only for RSource
and RLayer
and should not be modified between
2 renders.
This code introduces the useRControl
hook which will allow you to easily insert React controls
into your map. This hook returns an HTMLDivElement
from the DOM corresponding to your control's
container. It should be used in conjunction with the createPortal
function of react-dom
to
correctly insert your JSX
code into your control.
Add some css code
That's it! Thanks for giving maplibre-react-components
a shot. We hope this tutorial gives you a
good start to creat beautiful maps. There's a lot more you can do with this library, so make sure
to check out all the APIs.