How to load google maps api using nextjs? - javascript

How do you load and use the google maps api using Nextjs?
1 - How do you load the api? I've tried to load it in _document.js:
import { Html, Head, Main, NextScript } from 'next/document'
import Script from 'next/script'
const source = `https://maps.googleapis.com/maps/api/js?key=${process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY}&libraries=places`
const Document = () => {
return (
<Html>
<Head>
<Script type="text/javascript" src={source} strategy="beforeInteractive" />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
export default Document
2 - How do you reference the API?
Something like: ? window.google.maps.places.AutocompleteService().getPlacePredictions()
But I get an error that google is undefined
I have also tried using npm libraries but none seem to work.
react-places-autocomplete
use-places-autocomplete

The Google Maps team provides a quick, helpful tutorial "How to load Maps JavaScript API in React" that uses the #react-google-maps/api package in a Next.js project. The code snippet below comes from the repo linked by the tutorial's author, #leighhalliday.
1. How to load the Google Maps JavaScript API
Pass your API key to useLoadScript
(a React hook provided by #react-google-maps/api that loads the Maps API)
Once loaded, return an instance of the GoogleMap component
In this simplified example, the initial location is memoized. But see the second example below for how you might use in conjunction with the Google Places API
You can optionally also add a Marker to the map
import { useMemo } from "react";
import { GoogleMap, useLoadScript, Marker } from "#react-google-maps/api";
export default function Home() {
const { isLoaded } = useLoadScript({
googleMapsApiKey: process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY,
});
if (!isLoaded) return <div>Loading...</div>;
return <Map />;
}
function Map() {
const center = useMemo(() => ({ lat: 44, lng: -80 }), []);
return (
<GoogleMap zoom={10} center={center} mapContainerClassName="map-container">
<Marker position={center} />
</GoogleMap>
);
}
2. How to add Autocomplete with the Places + Google Maps API's
The Google Maps team provide a second tutorial to implement search + autocomplete in your map that leverages the use-places-autocomplete package. You can also find the full code in #leighhalliday's repo example.

Related

react-map-gl MAP component not sending over access_token

I'm trying to get a map to display using this documentation:
https://github.com/visgl/react-map-gl/blob/7.0-release/examples/get-started/basic/app.js
https://visgl.github.io/react-map-gl/docs/get-started/get-started
import * as React from 'react';
import Map, {Marker} from 'react-map-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
function App() {
const MAPBOX_TOKEN = process.env.NEXT_PUBLIC_MY_MAPBOX_API_TOKEN;
return (
<Map
initialViewState={{
latitude: 41.5801,
longitude: -71.4774,
zoom: 14
}}
style={{width: 800, height: 600}}
mapStyle="mapbox://styles/mapbox/streets-v9"
mapboxAccessToken={MAPBOX_TOKEN}
>
</Map>
);
}
export default App;
I also have a .env.local file with
NEXT_PUBLIC_MY_MAPBOX_API_TOKEN="api_key here"
The map does not display in the browser.
In the browser console, I get an error https://api.mapbox.com/styles/v1/mapbox/streets-v9?access_token=no-token.
So I think for some odd reason, react is not sending over the mapboxAccessToken through the Map component. No idea why.
I'm also going to paste the full console here in case I missed anything:
browser console
I have also tried to paste the api key directly into mapboxAccessToken.
Also tried using REACT_APP_MAPBOX_ACCESS_TOKEN instead.
No luck. This is getting ridiculous and I am starting to think they decommissioned react-map-gl.

Problem with iFrame in React rendering another app (flutter app)

I have a React app that is using an iFrame to render another app that was made in flutter (see the first image):
The flutter app is hosted in a certain domain (so it's like a micro frontend). The app in React is the dashboard and is hosted somewhere else (different than the flutter app)
My problem is that when testing the flutter app directly in the hosted URL, it works as expected. When you click on the name of one person, a sidebar opens with some information and a button "Gestion oferta".
When you click on the button, it should take you to this other view:
So this works as expected if I test the flutter app directly in the URL where it is hosted, but when I click on that button inside the react dashboard, it does not behave as expected, it just shows another instance of the same react app (dashboard) inside the iFrame, like this:
Here is my code for this component in the react app that renders the iFrame, in which I call the URL for the flutter app:
import { Fragment } from "react";
import { css } from '#emotion/react'
import Head from "next/head";
import DashboardLayout from "../../../layouts/DashboardLayout";
import { getTenantByCompanySiap } from "../../../helpers/tentant";
import { UAT, PROD, getEnv } from "../../../helpers/env";
export { getSSProps as getServerSideProps } from '../../../lib/Page'
export default function NuevaSolicitudPage(props) {
const tenant = getTenantByCompanySiap(props.infoRh?.codeCompanySIAP)
const branch = props.infoRh?.codeBranch
const user = props.employeeData?.email
const getCampanas = () => {
const env = getEnv();
const url = {
[UAT]: `https://url-for-testing`,
[PROD]: `https://other-url-for-production`
};
return url[env] || url[UAT];
};
const url = getCampanas()
return (
<Fragment>
<Head>
<title>Gestión de cartera | Campañas</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<DashboardLayout
{...props}
title="Campanas"
>
<iframe
src={url}
css={css`
width: 100%;
height: 100%;
`}
frameBorder="0"
/>
</DashboardLayout>
</Fragment>
);
}
I do not have access to the flutter app code, I only consume it and show it in the iFrame, but I heard from someone that I need to configure some files in order to display flutter apps in an iFrame in react, but he is also not sure. I have searched for something like this but could not find anything relevant to this problem because the app is showing, it just does not behave as expected.
Can somebody give me an advice on how to solve this issue? Thanks in advance.
This issue had to do with the cookies, somehow the cookie to store the user session got lost/erased, so whenever you have something similar and you use cookies for user sessions, check if they are stored and used properly.

Error: An API access token is required to use Mapbox GL

I am using react-gl library to use the map-api using mapbox. I have created an account mapbox as well still it is showing the error depicted in the picture.
Here is my code for app.js
import * as React from 'react';
import Map from 'react-map-gl';
function App() {
return (
<Map
initialViewState={{
longitude: -122.4,
latitude: 37.8,
zoom: 14
}}
mapboxApiAccessToken = {process.env.REACT_APP_MAPBOX}
style={{width: 600, height: 400}}
mapStyle="mapbox://styles/mapbox/streets-v9"
/>
);
}
export default App
Here is the error:
I faced the same problem. You must to change mapboxApiAccessToken to mapboxAccessToken.
Big shout out to Dani Pérez. Apparently his answer is correct. Just to add on to his answer, in react-map-gl v7.0, they decided to rename various props and one of those props is mapboxApiAccessToken
Renamed props for better consistency with the wrapped library:
mapboxApiAccessToken is now mapboxAccessToken
This is mentioned in their Upgrade guide:
https://visgl.github.io/react-map-gl/docs/upgrade-guide

Is there a way to import a script package from URL?

I'm using React and I want to use a package which can only retrieved as an URL. In HTML it's easy to import using the script tag, but how to import to a JavaScript file?
What I want is to convert this
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
into something like this
import 'https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true'
Based on your comment when you import it directly in your html:
It throws an error which says that the objects of the script aren't
defined
I think the best approach here is to not try to import the js in another js file, but use the React google maps library instead, so you don't go through these hacks.
Try it and let us know.
The reason for this answer is that, even if you get the script working by adding another js file into your own js file, google maps api js will do more things that will give you trouble and issues in React (like the one you are having right now), and these issues have already been solved by this library.
Have a read at the official documentation to see if it works for you.
Example
There is a good tutorial and very basic example using this library here.
Example of using latitude and longitude (taken from this tutorial):
const GoogleMapExample = withGoogleMap(props => (
<GoogleMap
defaultCenter = { { lat: 40.756795, lng: -73.954298 } }
defaultZoom = { 13 }
>
</GoogleMap>
));
return(
<div>
<GoogleMapExample
containerElement={ <div style={{ height: `500px`, width: '500px' }} /> }
mapElement={ <div style={{ height: `100%` }} /> }
/>
</div>
);
Alternative library
Alternatively, you could use this library, as it is another react library for rendering google maps.
google-map-react
You can also follow this tutorial with this library.
These libraries have plenty of supporters and stars, meaning that you can always count on updates and helpful information.

`Google Maps API warning: NoApiKeys ` when trying to access Youtube Data Api v3

I'm following the Modern Redux With React tutorial, and trying to access the Youtube Data API v3, but in Chrome console I get the error Google Maps API warning: NoApiKeys. I'm not sure why I'm getting a Google Maps warning, because I registered an API key for Youtube.
Clicked Go to Credentials.
Clicked "API Key".
Clicked "Browser".
Set name and clicked create.
Copied and pasted API into JS file.
import React, {Component} from 'react';
import * as ReactDOM from "react/lib/ReactDOM";
import YTSearch from 'youtube-api-search';
import SearchBar from './components/search_bar';
const API_KEY = 'AIzaSyD9WN2t4lhIZ5Es34jwaerM98r2nSutLJs';
class App extends Component {
constructor(props) {
super(props);
this.state = {videos: []};
YTSearch({key: API_KEY, term: 'surfboards'}, (videos) => {
console.log(data);
this.setState({videos});
});
}
render() {
return (
<div>
<SearchBar />
</div>
);
}
}
ReactDOM.render(<App />, document.querySelector('.container'));
This is because you have "maps.googleapis.com/maps/api/js" in your index.html file. Comment out that line to prevent google maps trying to load up without a key
You must be loading the Google Maps API without specifying an API key.
Have a look in the Network tab of Chrome Dev Tools and see if anything's loading /maps/api/js - then try and track down which part of your code is pulling in the Google Maps API.

Categories