Skip to content

Address Suggestions via Google Places on Custom Input Fields

PLUS

The address autocomplete that WP-ImmoMakler uses in the radius search is available from version 5.60.0 as a reusable library on any input field on your website. You can use it, for example, to equip a contact form, an estate agent finder, or a custom filter with the same suggestions — including keyboard navigation, caching, and protection for your Google API key.

For the library to be active on a page, the following prerequisites must be met:

  • You are using the Plus edition of WP-ImmoMakler.
  • Google services are enabled in the WordPress backend (wp-admin) under WP-ImmoMakler → Integrations → Geo Services and a valid Google Maps Geocoding API Key is configured.

If both conditions are met, WP-ImmoMakler automatically loads the script assets-plus/js/places-autocomplete.js on every front-end page (deferred). If the script finds no matching input field on the page, it has no further effect — no requests are sent to Google.

Section titled “Option 1: Via HTML Attribute (Recommended)”

Add the attribute data-immomakler-autocomplete to an <input> element. The library automatically detects the field and attaches itself:

<input
type="text"
name="address"
placeholder="Postcode, city or street"
data-immomakler-autocomplete
autocomplete="off"
>

When the user selects a suggestion, WP-ImmoMakler inserts the formatted address text into the field and fires a CustomEvent named immomakler:place-selected on the same element. The event contains the address text (label) and the Google Place ID (placeId) in the detail object:

const input = document.querySelector('input[name="address"]');
input.addEventListener('immomakler:place-selected', (event) => {
console.log(event.detail.label); // "Main Street 1, 20095 Hamburg, Germany"
console.log(event.detail.placeId); // "ChIJ..."
});

If the input field is inserted into the page dynamically (for example, in a modal), attach the library explicitly:

const input = document.getElementById('my-address-field');
window.ImmoMaklerPlacesAutocomplete.attach(input, {
minLength: 4, // Minimum characters before the first request (default: 3)
maxResults: 5, // Maximum number of suggestions (default: 8)
debounceMs: 200 // Typing delay in milliseconds (default: 140)
});

To remove the binding — for example when closing a modal — use detach:

window.ImmoMaklerPlacesAutocomplete.detach(input);

attach and detach accept either a DOM element or a CSS selector.

You can also specify the options from Option 2 directly in the data-immomakler-autocomplete attribute as JSON:

<input
type="text"
name="address"
data-immomakler-autocomplete='{"minLength": 4, "maxResults": 5}'
>

WP-ImmoMakler provides three ways for the browser script to fetch address suggestions — a fast one and two that go through the full WordPress stack:

  1. Fast-API Proxy (default, fast). A standalone PHP script at wp-content/cache/immomakler/fast-api/immomakler-autocomplete.php that does not load WordPress. It verifies a signed HMAC token, performs a same-origin check and a per-IP rate limit, calls Google Places via cURL, and returns JSON. A request typically takes 5–15 ms instead of 100–500 ms (WordPress bootstrap with all active plugins).
  2. REST endpoint (fallback). POST /wp-json/immomakler/v1/places/autocomplete — runs via index.php, goes through the regular hooks, and returns the same suggestions.
  3. admin-ajax endpoint (second fallback). POST /wp-admin/admin-ajax.php?action=immomakler_places_autocomplete — kicks in when the REST API is unavailable on the site (for example because it has been disabled by a plugin or filter).

The browser script tries path 1 first, then automatically falls back to path 2 and finally to path 3. The end result is functionally identical for the user; only the latency differs.

With every request, the browser script sends along a session token. It groups together the requests belonging to one search. Mapbox bills address suggestions per session. Google also recommends sessions, but only bills them as a session if it is completed with a Place Details request. WP-ImmoMakler does not make such a request, so Google bills every suggestion request individually.

From version 5.70.0, a token covers exactly one search: it ends as soon as the visitor selects a suggestion or submits the form, and after three minutes without a request. The next input then starts a new session. The token lives only in the page’s memory, so every page load starts with a new one. Up to version 5.69, a single token applied to all searches within a browser tab.

If your compliance or security policies require that no PHP files outside the regular WordPress bootstrap are executable, you can disable the Fast-API proxy in the WordPress backend (wp-admin) under WP-ImmoMakler → Integrations → Geo Services using the Use Fast-API Proxy checkbox. Address autocomplete will then run exclusively via the REST endpoint (with admin-ajax as a second fallback), and the proxy script will be removed from the filesystem when you save.

Alternatively, you can block the path wp-content/cache/immomakler/fast-api/*.php via a server rule (.htaccess, Nginx) — the script detects this (HTTP 403) and automatically switches to the REST fallback without requiring any changes to the plugin.

All three paths are publicly reachable, and every request that is not answered from the cache is billed to the map service through your API key. So that an automated script neither drives up your bill nor exhausts your quota, WP-ImmoMakler answers at most 600 billed requests per hour per IP address. Suggestions served from the cache do not count towards this and continue to be delivered afterwards.

Typing a place name generates roughly 10 to 15 requests, depending on its length. The limit therefore corresponds to more than 40 complete searches per hour from the same IP address, even if several visitors share an address, for example on an office network.

Once the limit is reached, the server responds with HTTP 429. On that page, the browser script then stops requesting further suggestions; the search field remains a normal input field, and the radius search continues to work with the text already typed. WP-ImmoMakler records rejected requests to the REST and admin-ajax endpoints in its spam-protection log; the Fast-API proxy does not load WordPress and does not log them.

You adjust the value with the filter immomakler_places_autocomplete_rate_limit; 0 disables the limit. It applies to all three paths, including the Fast-API proxy:

// Allow 1,200 billed requests per IP address and hour:
add_filter( 'immomakler_places_autocomplete_rate_limit', fn () => 1200 );

If your website is behind a reverse proxy or CDN that forwards every request with its own IP address, all visitors share a single limit. In this case, pass the actual visitor IP through the filter immomakler_rate_limit_client_fingerprint. The Fast-API proxy does not load WordPress and always reads REMOTE_ADDR; in this case, either disable it or configure your web server so that REMOTE_ADDR contains the visitor IP.

Section titled “Limiting Requests When Submitting the Radius Search”

When a visitor submits the radius search, WP-ImmoMakler converts the entered location into coordinates on the server (geocoding). This request is also billed by the chosen geo service through your API key, unless the location is already cached. Because the overview page is publicly accessible via the ?center= parameter, a separate limit also applies here: at most 100 billed geocoding requests per hour per IP address.

A search for a new location costs one geocoding request; an ambiguous place name outside your region costs at most three requests. Locations that have already been searched for, as well as paging and sorting, do not count. The limit is therefore sufficient for many visitors sharing a single IP address.

Once the limit is reached, the overview page shows all properties matching the remaining search criteria, with a notice above the results that the radius search is currently unavailable. The entered location remains in the search field. Locations from the cache continue to work. Property alerts that WP-ImmoMakler runs via WP-Cron are not subject to this limit. WP-ImmoMakler never geocodes input longer than 200 characters.

You adjust the value with the filter immomakler_radius_search_geocode_rate_limit; 0 disables the limit:

// Allow 300 billed geocoding requests per IP address and hour:
add_filter( 'immomakler_radius_search_geocode_rate_limit', fn () => 300 );

This limit also identifies visitors by their IP address; the note about the filter immomakler_rate_limit_client_fingerprint above applies here as well.

The library is deliberately designed to work with aggressively caching setups (WP Rocket, W3 Total Cache, LiteSpeed Cache, WP Super Cache, Cloudflare APO):

  • No security token in the HTML. Before version 5.60.0, WP-ImmoMakler wrote a token valid for 15 minutes into the page source. On cached pages this token was already expired for the first visitor. From version 5.60.0 onwards the token is fetched on first focus of the input field via the non-cacheable endpoint /wp-json/immomakler/v1/places/token.
  • Multi-stage fallback. If the fast proxy fails (for example because a token has expired), the library automatically fetches a new one and retries. If the proxy continues to be unavailable, requests fall back transparently to the WordPress REST API and finally to admin-ajax. Only if the request limit has been reached (HTTP 429) does the chain end immediately (see above).

If your caching plugin handles REST routes in an unusual way, exclude the path /wp-json/immomakler/v1/places/* from cache processing.

Three filters influence the behaviour of the library:

// Do not insert the script automatically into the footer — load it yourself via
// wp_enqueue_script( 'immomakler-places-autocomplete' ) on specific pages:
add_filter( 'immomakler_places_autocomplete_auto_enqueue', '__return_false' );
// Token lifetime (in seconds, default 900 = 15 minutes):
add_filter( 'immomakler_places_token_ttl', fn () => 600 );
// Minimum characters / maximum suggestions / typing delay:
add_filter( 'immomakler_places_autocomplete_min_length', fn () => 4 );
add_filter( 'immomakler_places_autocomplete_max_results', fn () => 5 );
add_filter( 'immomakler_places_autocomplete_debounce_ms', fn () => 200 );