20
loading...
This website collects cookies to deliver better user experience
npm init @vitejs/app [PROJECT_NAME]
cd [PROJECT_NAME]
npm install
npm run dev
3000
:npm install react-leaflet leaflet axios
// @src/main.jsx
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import "leaflet/dist/leaflet.css"; // <- Leaflet styles
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
);
// @src/app.jsx
import React from "react";
import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";
const App = () => {
const position = [51.505, -0.09];
return (
<MapContainer
center={position}
zoom={13}
scrollWheelZoom={true}
style={{ minHeight: "100vh", minWidth: "100vw" }}
>
<TileLayer
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Marker position={position}>
<Popup>
A pretty CSS3 popup. <br /> Easily customizable.
</Popup>
</Marker>
</MapContainer>
);
};
export default App;
useMap
:// @src/hooks/index.jsx
export const useMap = () => {
// Logic goes here
};
useState
hook, and in it we will store our latitude and longitude positions. I will want the initial state to be in Nantes, France but you can choose another location.// @src/hooks/index.jsx
import { useState } from "react";
export const useMap = () => {
const [position, setPosition] = useState({
lat: 47.21725,
lng: -1.55336,
});
// More logic goes here
};
useEffect
hook to make it run only when the page is rendered for the first time. And we know that the function's return is just going to be the position.// @src/hooks/index.jsx
import { useState, useEffect } from "react";
export const useMap = () => {
const [position, setPosition] = useState({
lat: 47.21725,
lng: -1.55336,
});
useEffect(() => {
// More logic goes here
}, []);
return { position };
};
// @src/hooks/index.jsx
import { useState, useEffect } from "react";
import axios from "axios";
export const useMap = () => {
const [position, setPosition] = useState({
lat: 47.21725,
lng: -1.55336,
});
useEffect(() => {
navigator.geolocation.getCurrentPosition(
({ coords }) => {
setPosition({ lat: coords.latitude, lng: coords.longitude });
},
(blocked) => {
// More logic goes here
}
}
);
}, []);
return { position };
};
// @src/hooks/index.jsx
import { useState, useEffect } from "react";
import axios from "axios";
export const useMap = () => {
const [position, setPosition] = useState({
lat: 47.21725,
lng: -1.55336,
});
useEffect(() => {
navigator.geolocation.getCurrentPosition(
({ coords }) => {
setPosition({ lat: coords.latitude, lng: coords.longitude });
},
(blocked) => {
if (blocked) {
const fetch = async () => {
try {
const { data } = await axios.get("https://ipapi.co/json");
setPosition({ lat: data.latitude, lng: data.longitude });
} catch (err) {
console.error(err);
}
};
fetch();
}
}
);
}, []);
return { position };
};
// @src/app.jsx
import React from "react";
import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";
import { useMap } from "./hooks";
const App = () => {
const { position } = useMap();
return (
<MapContainer
center={position}
zoom={4.5}
scrollWheelZoom={true}
style={{ minHeight: "100vh", minWidth: "100vw" }}
>
<TileLayer
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Marker position={position}>
<Popup>
A pretty CSS3 popup. <br /> Easily customizable.
</Popup>
</Marker>
</MapContainer>
);
};
export default App;
.env
to store our environment variables. In the Style URL link you will have the username and the style id.VITE_USERNAME=
VITE_STYLE_ID=
VITE_ACCESS_TOKEN=
// @src/app.jsx
import React from "react";
import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";
import { useMap } from "./hooks";
const { VITE_USERNAME, VITE_STYLE_ID, VITE_ACCESS_TOKEN } = import.meta.env;
// Hidden for simplicity
<TileLayer />
component, we're going to replace the attribution and the url. In the url we will add the link to get Mapbox tiles by dynamically passing the values of our environment variables. Just like we're going to give Mapbox credits in attribution. Like this:// @src/app.jsx
// Hidden for simplicity
const App = () => {
const { position } = useMap();
return (
<MapContainer
center={position}
zoom={4.5}
scrollWheelZoom={true}
style={{ minHeight: "100vh", minWidth: "100vw" }}
>
<TileLayer
attribution='Imagery © <a href="https://www.mapbox.com/">Mapbox</a>'
url={`https://api.mapbox.com/styles/v1/${VITE_USERNAME}/${VITE_STYLE_ID}/tiles/256/{z}/{x}/{y}@2x?access_token=${VITE_ACCESS_TOKEN}`}
/>
// Hidden for simplicity
</MapContainer>
);
};
// @src/app.jsx
import React from "react";
import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";
import { useMap } from "./hooks";
const { VITE_USERNAME, VITE_STYLE_ID, VITE_ACCESS_TOKEN } = import.meta.env;
const App = () => {
const { position } = useMap();
return (
<MapContainer
center={position}
zoom={4.5}
scrollWheelZoom={true}
style={{ minHeight: "100vh", minWidth: "100vw" }}
>
<TileLayer
attribution='Imagery © <a href="https://www.mapbox.com/">Mapbox</a>'
url={`https://api.mapbox.com/styles/v1/${VITE_USERNAME}/${VITE_STYLE_ID}/tiles/256/{z}/{x}/{y}@2x?access_token=${VITE_ACCESS_TOKEN}`}
/>
<Marker position={position}>
<Popup>
A pretty CSS3 popup. <br /> Easily customizable.
</Popup>
</Marker>
</MapContainer>
);
};
export default App;