N
Nuxt4w ago
Hugo

Add google map with nuxt

Hi guys, do you have any idea on how to add google map with nuxt project ? Both vue3-google-map and @fawmi/vue-google-maps doesn't work for me, got error like hydratation, or module doesn' t existe. I'm starting to go crazy
23 Replies
kapa.ai
kapa.ai4w ago
Hi @Hugo. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- I understand your frustration with implementing Google Maps in your Nuxt project. Hydration errors are common when working with components that interact with browser-specific APIs like Google Maps. Based on the knowledge sources, there are a few approaches to solve this issue: Transpiling the Libraries The most common solution for these types of errors is to add the Google Maps libraries to your build.transpile array in your nuxt.config.js or nuxt.config.ts file:
export default defineNuxtConfig({
build: {
transpile: ['vue3-google-map', '@fawmi/vue-google-maps']
}
})
export default defineNuxtConfig({
build: {
transpile: ['vue3-google-map', '@fawmi/vue-google-maps']
}
})
This approach is similar to how other map libraries like Leaflet need to be handled in Nuxt, as mentioned in a Stack Overflow solution where someone had to transpile Leaflet to fix PNG tile errors Stack Overflow Post. Handling Hydration Errors Hydration errors occur when the server-rendered HTML doesn't match what the client-side JavaScript tries to render. This is common with map components because: 1. They often rely on browser-specific APIs not available during server-side rendering 2. They might generate different content on server vs client To solve this, you can: 1. Make the component client-only by creating a wrapper component with the client-only tag:
<template>
<client-only>
<GoogleMap :options="mapOptions" />
</client-only>
</template>
<template>
<client-only>
<GoogleMap :options="mapOptions" />
</client-only>
</template>
2. Or use the .client suffix in your component file name (e.g., GoogleMap.client.vue) Alternative Approach If you're still facing issues, you might want to try installing a Google Maps module using Nuxi's module command:
npx nuxi module add [google-maps-module-name]
npx nuxi module add [google-maps-module-name]
This will automatically install the module and update your nuxt.config file Nuxt Module Commands. If you continue to experience problems, consider creating a minimal reproduction of your issue and sharing it in the Nuxt GitHub discussions or issues. The Nuxt community is very helpful and can provide more specific guidance for your particular setup Getting Help. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4w ago
<@122807566475591680> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Hugo
HugoOP4w ago
@kapa.ai How to add google map without library
kapa.ai
kapa.ai4w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- I understand you want to add Google Maps to your Nuxt project without using a third-party library. This is definitely possible by directly using the Google Maps JavaScript API. Here's how you can implement Google Maps in your Nuxt project: 1. First, you'll need to add the Google Maps script to your application. You can use the useHead() utility or add it to your Nuxt configuration:
// In your component or plugin
useHead({
script: [
{
textContent: `/* Your Google Maps initialization code */`,
tagPosition: "bodyClose",
},
],
});

// OR in nuxt.config.ts
export default defineNuxtConfig({
app: {
head: {
script: [
{
textContent: `/* Your Google Maps initialization code */`,
tagPosition: "bodyClose",
}
]
}
}
})
// In your component or plugin
useHead({
script: [
{
textContent: `/* Your Google Maps initialization code */`,
tagPosition: "bodyClose",
},
],
});

// OR in nuxt.config.ts
export default defineNuxtConfig({
app: {
head: {
script: [
{
textContent: `/* Your Google Maps initialization code */`,
tagPosition: "bodyClose",
}
]
}
}
})
The textContent property allows you to add inline scripts, which is perfect for initializing Google Maps Stack Overflow Post. 2. Alternatively, you can create a client-side plugin to load the Google Maps script:
// plugins/google-maps.client.js
export default defineNuxtPlugin(() => {
return {
provide: {
initGoogleMaps: (apiKey) => {
return new Promise((resolve, reject) => {
if (window.google && window.google.maps) {
resolve(window.google.maps);
return;
}

const script = document.createElement('script');
script.src = `<https://maps.googleapis.com/maps/api/js?key=${apiKey}&callback=initMap`;>
script.async = true;
script.defer = true;

window.initMap = () => {
resolve(window.google.maps);
};

script.onerror = reject;
document.head.appendChild(script);
});
}
}
}
})
// plugins/google-maps.client.js
export default defineNuxtPlugin(() => {
return {
provide: {
initGoogleMaps: (apiKey) => {
return new Promise((resolve, reject) => {
if (window.google && window.google.maps) {
resolve(window.google.maps);
return;
}

const script = document.createElement('script');
script.src = `<https://maps.googleapis.com/maps/api/js?key=${apiKey}&callback=initMap`;>
script.async = true;
script.defer = true;

window.initMap = () => {
resolve(window.google.maps);
};

script.onerror = reject;
document.head.appendChild(script);
});
}
}
}
})
3. Then in your component:
<template>
<div>
<div ref="mapContainer" style="width: 100%; height: 400px;"></div>
</div>
</template>

<script setup>
const { $initGoogleMaps } = useNuxtApp();
const mapContainer = ref(null);

onMounted(async () => {
try {
const googleMaps = await $initGoogleMaps('YOUR_API_KEY');
const map = new googleMaps.Map(mapContainer.value, {
center: { lat: -34.397, lng: 150.644 },
zoom: 8,
});
// Add markers, etc.
} catch (error) {
console.error('Failed to load Google Maps', error);
}
});
</script>
<template>
<div>
<div ref="mapContainer" style="width: 100%; height: 400px;"></div>
</div>
</template>

<script setup>
const { $initGoogleMaps } = useNuxtApp();
const mapContainer = ref(null);

onMounted(async () => {
try {
const googleMaps = await $initGoogleMaps('YOUR_API_KEY');
const map = new googleMaps.Map(mapContainer.value, {
center: { lat: -34.397, lng: 150.644 },
zoom: 8,
});
// Add markers, etc.
} catch (error) {
console.error('Failed to load Google Maps', error);
}
});
</script>
Remember to handle hydration issues by using <ClientOnly> around your map component or by using the .client.vue suffix for your component file to ensure it only renders on the client side. This approach gives you full control over the Google Maps implementation without relying on third-party libraries, which can help avoid compatibility issues with Nuxt. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4w ago
<@122807566475591680> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Hugo
HugoOP4w ago
@kapa.ai I got this error Failed to load Google Maps InvalidValueError: Map: Expected mapDiv of type HTMLElement but was passed null.
kapa.ai
kapa.ai4w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- I understand you're encountering an error with Google Maps in your Nuxt application. This specific error occurs when the Google Maps API tries to initialize a map but can't find the DOM element to attach it to. The error "Map: Expected mapDiv of type HTMLElement but was passed null" typically happens because: 1. The DOM element reference is null when the map is being initialized 2. The timing of when the map is initialized doesn't align with when the DOM is ready Here's how to fix this issue in your Nuxt application:
<template>
<div>
<client-only>
<div ref="mapContainer" style="width: 100%; height: 400px;"></div>
</client-only>
</div>
</template>

<script setup>
const mapContainer = ref(null);

onMounted(async () => {
// Make sure to wait a tick for the DOM to be fully rendered
await nextTick();

if (mapContainer.value) {
const googleMaps = window.google.maps;
const map = new googleMaps.Map(mapContainer.value, {
center: { lat: -34.397, lng: 150.644 },
zoom: 8,
});
// Add markers, etc.
} else {
console.error('Map container element not found');
}
});
</script>
<template>
<div>
<client-only>
<div ref="mapContainer" style="width: 100%; height: 400px;"></div>
</client-only>
</div>
</template>

<script setup>
const mapContainer = ref(null);

onMounted(async () => {
// Make sure to wait a tick for the DOM to be fully rendered
await nextTick();

if (mapContainer.value) {
const googleMaps = window.google.maps;
const map = new googleMaps.Map(mapContainer.value, {
center: { lat: -34.397, lng: 150.644 },
zoom: 8,
});
// Add markers, etc.
} else {
console.error('Map container element not found');
}
});
</script>
Key points to ensure this works: 1. Use client-only to ensure the map container only renders on the client side 2. Use await nextTick() to ensure the DOM is fully rendered before initializing the map 3. Add a check to verify that mapContainer.value exists before trying to initialize the map 4. Make sure your Google Maps script is properly loaded before trying to access window.google.maps If you're still experiencing issues, you might need to delay the map initialization slightly to ensure the DOM is fully ready, or check if there are any CSS issues that might be causing your container element to have zero dimensions. Remember that when working with external APIs like Google Maps in Nuxt, handling the client-side only nature of these APIs is crucial to avoid hydration errors and null reference issues. Let me know if this helps resolve your issue! ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4w ago
<@122807566475591680> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
dmarr
dmarr4w ago
I can help you with this in a bit. Maplibre-vue-plugin with maplibre-google-maps is how I did it
Hugo
HugoOP4w ago
i reed webgl, is it performant ?
dmarr
dmarr4w ago
Yea
Hugo
HugoOP4w ago
do you mind if you send me an exemple because i still always have hydratation missmatch even when i use client only component
dmarr
dmarr4w ago
https://github.com/Gugustinette/nuxt-maplibre clone that because using it as a module doesn’t actually work
GitHub
GitHub - Gugustinette/nuxt-maplibre: A Nuxt module to use MapLibre
A Nuxt module to use MapLibre. Contribute to Gugustinette/nuxt-maplibre development by creating an account on GitHub.
dmarr
dmarr4w ago
GitHub
GitHub - traccar/maplibre-google-maps: MapLibre plugin to add Googl...
MapLibre plugin to add Google Maps. Contribute to traccar/maplibre-google-maps development by creating an account on GitHub.
dmarr
dmarr4w ago
any luck?
dmarr
dmarr3w ago
GitHub
GitHub - marr/nuxt-maplibre: Maplibre module for nuxt
Maplibre module for nuxt. Contribute to marr/nuxt-maplibre development by creating an account on GitHub.
dmarr
dmarr3w ago
you will need a .env in playground with keys.
NUXT_PUBLIC_MAP_TILER_KEY=
NUXT_PUBLIC_GOOGLE_MAP_TILES_API_KEY=
NUXT_PUBLIC_MAP_TILER_KEY=
NUXT_PUBLIC_GOOGLE_MAP_TILES_API_KEY=
you only need the google one if thats what you require
Hugo
HugoOP3w ago
Hi, you told me to clone that because adding it via module doesn't work, but i never did something like this before, if i clone and download the repo, where should i put it in my project ? Thank you for your answer, i will try to make maplibre works, it look very interesting
dmarr
dmarr3w ago
That link to my repo might actually work
Hugo
HugoOP3w ago
i'm sorry, nothing works for me, i think i will just give-up. Btw, i don't need especialy a google map, openstree is okay. My component is named with .client.vue, it has <ClientOnly> and i have hydratation issues. i'm quiet exhausted. Thank you for your help
dmarr
dmarr3w ago
Bummer man. It should have been as easy as pulling down my repo and running dev
Hugo
HugoOP3w ago
Maybe but i have to add this on my project.. i will retry so i just tried to download and run dev your repo and it the project doesn't work Vite errors, Error 500 Thank you that works perfectly !
plex
plex3w ago
What's wrong with Nuxt Scripts, which has a Google Maps implementation? https://scripts.nuxt.com/scripts/content/google-maps
Nuxt Scripts
Google Maps · Nuxt Scripts
Show performance-optimized Google Maps in your Nuxt app.

Did you find this page helpful?