Skip to main content

Embedding Google Maps on Your Website

This page explains how to embed Google Maps on your own website and update the location information from the frontend.

Overview

Kuroco provides an extension format for storing location information on Google Maps. If you want to input location information through the Kuroco management screen, you can simply click on the location on the map displayed in the content editing screen of the Kuroco management screen to specify the location. However, when displaying a map on the front end or providing an interface to save specified location information, implementation using an API is necessary. This tutorial explains how to display the Google Maps interface on the frontend and update the location information.

Prerequisites

info

This page assumes that you have already set up a project in Kuroco.
If you haven't set up a project yet, please refer to the following tutorial.
Kuroco Beginner's Guide

info

This tutorial is written with the following versions:
Nuxt2: v2.15.8
Nuxt3: v3.8.0

Setting up Google Maps

Creating a New Project in GCP

First, create a new project in the Google Cloud Platform (GCP).
Log in to the Google Cloud Platform and click on the project dropdown in the header.
Click on "NEW PROJECT" in the popup that appears.

Image from Gyazo

On the new project settings page, enter a project name of your choice and click "Create".

Image from Gyazo

A new project has been created.

Enabling APIs

Next, enable the necessary APIs in the GCP console.

First, select the project you created from the project dropdown in the header of the GCP console.

Image from Gyazo

Then, select "APIs & Services" - "Enabled APIs $ services" from the sidebar.

Image from Gyazo

When you select "Library" from the sidebar, the API library page will be displayed.

Image from Gyazo

Here, search for "Places API" and "Maps JavaScript API" and enable each API.

Image from Gyazo

Image from Gyazo

Next, generate an API key. Select "Credentials" from the sidebar, and click on "+ Create Credentials".

Image from Gyazo

Select API key.

Image from Gyazo

An API key will be generated. Please keep it as you will need it later.

Image from Gyazo

Setting up Allowed Domains

By registering the domain of your website with the API key, you can control the usage of the API and prevent unauthorized access from other websites.

On the credentials page, select "Edit API key" from the button on the right of the API key you created earlier.

Image from Gyazo

Enter a name for the API key and select "Website" from the application restrictions settings.

Image from Gyazo

Click the "ADD" button, enter the domain of the site you plan to use, and click "DONE".

Image from Gyazo

Kuroco Settings

Content Definition Settings

In the Kuroco content definition, set the following items in any optional section of the extended item.

Item NameInput Value
Item NameMap (Google Maps)
Identifiergmap
Item SettingMap

Image from Gyazo

Creating Endpoints

Create an endpoint for retrieve map location information from Kuroco's content.
Please enter as follows:

Item NameInput Value
Path/rmcs-api/(API ID)/map/details/{topics_id}
ModelContent - Topics - details
API Request Restriction(Select the group or member filter that allows viewing)
Cache86400
topics_group_id(Content structrue ID of the content to be displayed)

Image from Gyazo

Image from Gyazo

Create an endpoint for changing the location information of the map.
Please enter as follows:

Item NameInput Value
Path/rmcs-api/(API ID)/map/update/{topics_id}
ModelContent - Topics - update
API Request Restriction(Select the group or member filter that allows changes)
topics_group_id(Content structrue ID of the content you want to update)
use_columnsgmap

Image from Gyazo

Image from Gyazo

Frontend Implementation

Install npm module

Install the npm module which provides Vue.js components for Google Maps.

npm install vue2-google-maps

Add GCP KEY to config

Add the generated API key to the website's configuration file (usually the config file). This allows the website to use the API. If you are implementing it with Nuxt.js, please add it as follows to .env or similar.

.env
BASE_URL=https://sample-service-site.g.kuroco.app
GCP_KEY=**************************************
tip

When using the contents of the .env file during deployment, you can either remove .env from .gitignore and manage the .env file on GitHub, or register the contents in GitHub Secrets and have GitHub Actions read and use them.

To read this constant, write following code.

nuxt.config.js
export default {
env: {
GCP_KEY: process.env.GCP_KEY
},
// (omitted)

plugins: [
// (omitted)
'@/plugins/vue2-google-maps.client'
],

(Nuxt2 only)

Add a file named vue2-google-maps.client.js to the plugins/ directory and write the following:

/plugins/vue2-google-maps.client.js
import Vue from 'vue';
import * as VueGoogleMaps from 'vue2-google-maps';

Vue.use(VueGoogleMaps, {
load: {
key: process.env.GCP_KEY,
libraries: 'places'
}
});

Implementation of a page displaying Google Maps

Let's display a Google Map on the website. Use the installed components and implement as follows:

/pages/map/details/_id.vue
<template>
<div class="container">
<h3>Map (Google Maps)</h3>
<form id="topics_edit" @submit.prevent="update">
<div>
<GmapMap
ref="gmap"
:center="mapCenter"
:zoom="gmap_zoom"
:map-type-id="gmap_type"
style="width: 500px; height: 300px"
>
<GmapMarker
v-if="markPlace"
:position="markPlace"
/>
</GmapMap>
</div>
</form>
</div>
</template>

<script>
export default {
async asyncData({ $axios, route }) {
const id = route.params.id;
const url = `/rcms-api/1/test/${id}`;

const contents = await $axios
.$get(url)
.then((response) => {
if (response.details) {
return response.details;
}
return {};
})
.catch((error) => {
console.log(error);
return {};
});
// Googleマップの初期状態をセット
let mapCenter = { lat: 35.66107078220203, lng: 139.7584319114685 };
let markPlace = null;
if (contents.gmap?.gmap_x && contents.gmap?.gmap_y) {
const lat = Number(contents.gmap.gmap_y);
const lng = Number(contents.gmap.gmap_x);
mapCenter = { lat, lng };
markPlace = { lat, lng };
}

return {
mapCenter,
markPlace,
id,
contents,
errors: []
};
},
computed: {
gmap_zoom() {
return Number(this.contents.gmap?.gmap_zoom) || 15;
},
gmap_type() {
return this.contents.gmap?.gmap_type || 'roadmap';
}
}
};
</script>
caution

Please adjust the URL of the endpoint you are using to your own.

The result of the execution is as follows.
Image from Gyazo

Implementation of a page updating Google Maps contents

Next, let's make it possible to update the location information from the frontend.

/pages/map/edit/_id.vue
<template>
<div class="container">
<h3>Map (Google Maps)</h3>
<div>
The position that is set changes when you click on the map. You can also set the zoom and other states.
</div>
<form id="topics_edit" @submit.prevent="update">
<div>
<form onsubmit="return false;">
<GmapAutocomplete
:options="{fields: ['geometry']}"
:select-first-on-enter="true"
@place_changed="setPlace"
/>
<GmapMap
ref="gmap"
:center="mapCenter"
:zoom="gmap_zoom"
:map-type-id="gmap_type"
style="width: 500px; height: 300px"
@click="mark($event)"
@zoom_changed="gmap_zoom = $event"
@maptypeid_changed="gmap_type = $event"
>
<GmapMarker
v-if="markPlace"
:position="markPlace"
/>
</GmapMap>
</form>
</div>
<input
type="submit"
value="Save"
>
</form>
</div>
</template>

<script>
export default {
async asyncData({ $axios, route }) {
const id = route.params.id;
const url = `/rcms-api/1/test/${id}`;

const contents = await $axios
.$get(url)
.then((response) => {
if (response.details) {
return response.details;
}
return {};
})
.catch((error) => {
console.log(error);
return {};
});
// Googleマップの初期状態をセット
let mapCenter = { lat: 35.66107078220203, lng: 139.7584319114685 };
let markPlace = null;
if (contents.gmap?.gmap_x && contents.gmap?.gmap_y) {
const lat = Number(contents.gmap.gmap_y);
const lng = Number(contents.gmap.gmap_x);
mapCenter = { lat, lng };
markPlace = { lat, lng };
}

return {
mapCenter,
markPlace,
id,
contents,
errors: []
};
},
computed: {
gmap_zoom: {
get() { return Number(this.contents.gmap?.gmap_zoom) || 15; },
set(val) { this.contents.gmap.gmap_zoom = String(val); }
},
gmap_type: {
get() { return this.contents.gmap?.gmap_type || 'roadmap'; },
set(val) { this.contents.gmap.gmap_type = val; }
}
},
methods: {
setPlace(place) {
if (place.geometry) {
this.markPlace = {
lat: place.geometry.location.lat(),
lng: place.geometry.location.lng()
};
if (place.geometry.viewport) {
this.$refs.gmap.fitBounds(place.geometry.viewport);
} else {
this.$refs.gmap.panTo(place.geometry.location);
}
}
},
mark(event) {
this.markPlace = {
lat: event.latLng.lat(),
lng: event.latLng.lng()
};
},
async update() {
const params = {
gmap: {
gmap_x: '',
gmap_y: '',
gmap_zoom: (this.contents?.gmap?.gmap_zoom || 15),
gmap_type: (this.contents?.gmap?.gmap_type || 'roadmap')
}
};
if (this.markPlace) {
params.gmap.gmap_x = String(this.markPlace.lng);
params.gmap.gmap_y = String(this.markPlace.lat);
}
await this.$axios.post(
'/rcms-api/1/update_news/' + this.$route.params.id,
params
).then((response) => {
if (response.data.errors?.length) {
console.log(response.data.errors);
}
this.errors = [];
}).catch((error) => {
console.log(error);
});
}
}
};
</script>
caution

Please adjust the URL of the endpoint you are using to your own.

The result of execution is as follows.
Image from Gyazo

When you click the save button, the position of the pin and the zoom state will be written to Kuroco's DB.

caution

In the above sample code, for simplicity, the page is displayed even in a non-logged-in state, but normally you would log in before making updates. Please refer to the following for information on logging in. Building a login page using Kuroco and Nuxt.js

With the above steps, you have embedded Google Maps on your website and enabled the ability to change the location information on your website just like in the Kuroco admin panel. By following these procedures, you can provide your website users with a great map experience.


Support

If you have any other questions, please contact us or check out Our Slack Community.