Locator Upgrade - OpenCms Steps
Search engines and AI assistants often cannot see your store finder. When they visit the page, your stores are not on it yet: they only appear later, on the visitor's screen. So your stores can be missing from search results and from the answers AI assistants give.
After these steps, every store finder page arrives with its stores already on it, with names, addresses and opening hours. Search engines and AI assistants can find each of your stores and show it. Your visitors see the store finder as usual.
It works for a store finder already on your site and for a new one. The steps are written for the developer who maintains the site's template and the web server in front of OpenCms.
Which way is yours
There are two ways, and your OpenCms version decides which ones you can take.
Find your OpenCms version: open the sitemap editor, and in its menu, top right, choose About. It says, for example, "This is OpenCms 22.0".
- a) OpenCms 21 or newer: the Uberall module does it, inside OpenCms. Follow a) With the Uberall module.
- b) OpenCms 10.5 or newer: the Apache or Nginx server in front of OpenCms does it. Follow b) Through your web server. It needs access to that server's configuration. On an older version, ask Uberall before you start.
On OpenCms 21 or newer, both work. Take one of them, not both.
What you need
Your render token, from Uberall
Your locator key, from Uberall. If the store finder is already on your site, it is the data-key of its snippet:
<div id="store-finder-widget" data-key="YOUR_LOCATOR_KEY"></div>
Your store finder's address: the page it is on, such as https://www.example.com/store-locator. Each store gets its own address under it
A developer who can change your site's template
For a): a workplace administrator, such as the Admin user, and the Uberall Store Finder module, a zip file: com.uberall.storefinder_latest.zip
For b): access to the configuration of the Apache or Nginx server in front of OpenCms
If the store finder is already on your site
After these steps, your store finder pages use only the settings saved at Uberall. What is set on the page itself no longer applies there:
- attributes on the store finder's
div, other thandata-key,data-language,data-countriesanddata-widgetoriginurl - settings your site's scripts pass to
UberallStorefinderMountorUberallStorefinderRestart, other thanwithoutMap
To find them, look in two places:
-
The store finder's
div, in the page's source: anydata-attribute other than the four above. -
Your site's scripts, in the page's source and in your site's JavaScript files: calls to
UberallStorefinderMountorUberallStorefinderRestart.
If you find any of these settings, send them to Uberall before you go on, to be saved with your store finder. Until then, leave the page as it is: the store finder keeps working as it does today.
If the div has data-baseurl, leave it out of the new snippet. With any address in it other than https://locator.uberall.com, the store finder does not take over the stores in the page: it shows them again on the visitor's screen.
If its addresses have #! in them today, check with Uberall that your store finder is set up without it: your server only sees the part of an address before #.
Your pages' title and description
Uberall gives every store finder page its own canonical link. The title, the description and the preview image for social media come from Uberall only when they are set up there:
- The store finder's main page, and its directory pages (the lists of stores by country, region or city): only what is set up at Uberall.
- A store's page: always a title and, when the store has one, a description: the store's name and short description, unless others are set up. The image is the store's photo.
So check with Uberall first that a title and a description are set up for your store finder, or send yours to be saved with it.
a) With the Uberall module
For OpenCms 21 or newer. It takes five steps: two in the workplace, one in your template, two in the page and sitemap editors.
Step a1: Import the module
In the workplace, open the Launchpad, then Modules. Click Import module, the cloud with an arrow. On Import via HTTP, click Select file, choose the zip file and click OK. When the import says "the module has been imported", click Close.
Step a2: Add your render token
In Modules, click com.uberall.storefinder, then Edit. On the Module parameters tab, click Add parameter, write your locator key and your token into the new line, joined by =, and click OK:
YOUR_LOCATOR_KEY=YOUR_RENDER_TOKEN
The token stays on your server. Visitors never see it. But an export of the module carries its parameters, so do not share one.
Importing the module again, to update it, clears its parameters: add the line again afterwards. To keep the token out of OpenCms instead, give the server that runs OpenCms an environment variable named UBERALL_RENDER_TOKEN, with the token, and restart it. One of the two is enough. The environment variable is for one store finder; for more, see More than one store finder.
Step a3: Let your template add the store finder's head tags
This step is for the developer of your template. In the template's <head>, put the tags that describe the page into this include: the title, the description, the canonical link, the og: and twitter: tags and the structured data (application/ld+json):
<cms:include file="/system/modules/com.uberall.storefinder/elements/head.jsp">
<cms:param name="head">
<title>...</title>
<meta name="description" content="...">
<link rel="canonical" href="...">
<!-- ... and the template's og:, twitter: and ld+json tags -->
</cms:param>
</cms:include>
On every page without the store finder, they stay as they are, and so does the page's caching. On the store finder's pages, the module replaces those that Uberall sends: see What changes on your store finder pages.
The rest of the head stays as it is. The template may stay cached: the module does its part anew for each visit.
Step a4: Put the store finder on its page
Open the store finder page in the page editor. If the store finder snippet is on it, in a text or in your template, remove it: the module puts it there itself.
Click Add content, find Uberall store finder and drag it to where the store finder goes. Open its settings and fill them in from your snippet:
| Setting | Value |
|---|---|
| Locator key | Your locator key: the snippet's data-key
|
| Language | The snippet's data-language, such as de. Empty if it has none |
| Countries | The snippet's data-countries. Empty if it has none |
| Store finder address | Your store finder's address, such as https://www.example.com/store-locator
|
| Without map | Check it if your snippet loads storeFinderWidget-v2-withoutMap.js
|
Without an address, the module uses the page's address as OpenCms links to it.
If Add content does not list Uberall store finder, your site's sitemap configuration leaves out functions, as sites on the Mercury template do. Open the sitemap editor, and in its menu choose Advanced, Sitemap configuration. On the Dynamic functions tab, add a Dynamic function to be added: /system/modules/com.uberall.storefinder/functions/store-finder.xml. Save, and add the store finder as above.
Step a5: Send every store's address to the store finder page
Each store's page lives at an address under the store finder, such as /store-locator/l/berlin/.... OpenCms has to answer all of them with the store finder page.
Open the sitemap editor, and in its menu choose Advanced, Aliases. Under Create new rewrite, fill in the pattern and the replacement with your own page, choose the action Passthrough, and click the + next to it. The replacement is the page's path in OpenCms, as the explorer shows it:
| Your store finder page | Pattern | Replacement | Action |
|---|---|---|---|
A folder, such as /store-locator/
|
/store-locator/.* |
/store-locator/index.html |
Passthrough |
A file, such as /service/shopfinder
|
/service/shopfinder/.* |
/service/shopfinder |
Passthrough |
Click Save. Then publish the store finder page.
Before OpenCms 21, the dialog offers Passthrough too, but store addresses still answer "Not Found": that is why this way needs OpenCms 21.
If a server or a CDN in front of OpenCms sends only some addresses on to it, check that it sends everything under /store-locator/.
Then check your site.
b) Through your web server
For OpenCms 10.5 or newer. Your Apache or Nginx server, in front of OpenCms, puts the stores into the page, as the guides for those servers describe. OpenCms serves the store finder page with the two includes on it.
Step b1: Connect your server to Uberall
Do step 1 of the guide for your server:
- Apache: Connect your server to Uberall
- Nginx: Connect your server to Uberall
Step b2: Turn on includes for the store finder, and send it every store's address
Each store's page lives at an address under the store finder, such as /store-locator/l/berlin/.... Your server answers all of them with the store finder page, at its address without a slash at the end, such as /store-locator, and fills in the includes on it. In the site's configuration, add this, with your store finder's address in place of /store-locator.
Every address under the store finder page then belongs to the store finder. Do not keep other pages or files under it.
Apache, in the same <VirtualHost> as step b1. Find out how it sends pages to OpenCms: look for a RewriteRule that puts a path in front of every address, such as RewriteRule !^/opencms/(.*)$ /opencms%{REQUEST_URI} [PT] in OpenCms's own Apache example.
a) No such RewriteRule, for example a ProxyPass "/" ... to OpenCms:
<LocationMatch "^/store-locator(/|$)">
Options +IncludesNOEXEC
SetOutputFilter INCLUDES
SSIErrorMsg "<!-- -->"
RequestHeader unset Accept-Encoding
</LocationMatch>
RewriteEngine on
RewriteRule ^/store-locator/ /store-locator [PT,L]
b) A RewriteRule that puts a path in front, such as /opencms: that path goes in front of the store finder's address in both places. Put the RewriteRule below before that one, and add the RewriteCond line right above that one, so the includes stay with your server:
<LocationMatch "^/opencms/store-locator(/|$)">
Options +IncludesNOEXEC
SetOutputFilter INCLUDES
SSIErrorMsg "<!-- -->"
RequestHeader unset Accept-Encoding
</LocationMatch>
RewriteRule ^/store-locator/ /opencms/store-locator [PT,L]
# ... and your own rule, with one more condition above it:
RewriteCond %{REQUEST_URI} !^/api/locator-fragments/
RewriteRule !^/opencms/(.*)$ /opencms%{REQUEST_URI} [PT]
Nginx, in the same server as step b1:
location = /store-locator {
ssi on;
proxy_set_header Accept-Encoding "";
# ... what your location for OpenCms has, such as its proxy_pass
}
location /store-locator/ {
rewrite ^ /store-locator last;
}
Copy into the first one what the location that sends your pages to OpenCms has, such as its proxy_pass. If that proxy_pass ends in a path, add the store finder's address to it: for proxy_pass http://127.0.0.1:8080/opencms/; write proxy_pass http://127.0.0.1:8080/opencms/store-locator;.
Copy every proxy_set_header line too, from that location and from its server and http blocks, such as proxy_set_header Host $host;. A location with a proxy_set_header of its own, as this one has, gets none of theirs, and OpenCms may then not know which site to serve.
The Accept-Encoding line makes OpenCms send the page uncompressed. Your server cannot fill in the includes of a compressed page.
Step b3: Put the store finder and its includes on the page
This step is for the developer of your template. Its <head> gets the first include on the store finder page, instead of the page's own title, description, canonical link and og: tags. Replace YOUR_LOCATOR_KEY with your locator key, and /store-locator/index.html with the store finder page's path in OpenCms, as the explorer shows it: a page in a folder is the folder's page file, usually index.html, and a page that is a file, such as /service/shopfinder, is that file. The c: and cms: tags are the ones OpenCms templates declare at their top.
Apache:
<c:choose>
<c:when test="${cms.requestContext.uri == '/store-locator/index.html'}">
<!--#include virtual="/api/locator-fragments/head?key=YOUR_LOCATOR_KEY&path=\${REQUEST_URI}" -->
</c:when>
<c:otherwise>
<!-- ... your title, description, canonical link and og: tags -->
</c:otherwise>
</c:choose>
The backslash in \${REQUEST_URI} keeps the template from reading it as one of its own expressions: your server gets ${REQUEST_URI}.
Nginx:
<c:choose>
<c:when test="${cms.requestContext.uri == '/store-locator/index.html'}">
<!--# include virtual="/api/locator-fragments/head?key=YOUR_LOCATOR_KEY&path=$request_uri" wait="yes" -->
</c:when>
<c:otherwise>
<!-- ... your title, description, canonical link and og: tags -->
</c:otherwise>
</c:choose>
The store finder's div gets the second include. Put it where the store finder goes: in a text on the page, in the editor's source code view, or in your template. With your locator key:
Apache:
<div id="store-finder-widget" data-key="YOUR_LOCATOR_KEY">
<!--#include virtual="/api/locator-fragments/body?key=YOUR_LOCATOR_KEY&path=${REQUEST_URI}" -->
</div>
<script src="https://locator.uberall.com/locator-assets/storeFinderWidget-v2.js"></script>
Nginx:
<div id="store-finder-widget" data-key="YOUR_LOCATOR_KEY">
<!--# include virtual="/api/locator-fragments/body?key=YOUR_LOCATOR_KEY&path=$request_uri" -->
</div>
<script src="https://locator.uberall.com/locator-assets/storeFinderWidget-v2.js"></script>
In a text, ${REQUEST_URI} needs no backslash. In your template it does, as in the head.
OpenCms's text editor keeps the include, but it may remove the <script> line when you save. If the page's source has no storeFinderWidget-v2.js after you save, put the script line into your template instead, before </body>, for the store finder page only:
<c:if test="${cms.requestContext.uri == '/store-locator/index.html'}">
<script src="https://locator.uberall.com/locator-assets/storeFinderWidget-v2.js"></script>
</c:if>
The snippet's settings and the includes must match, as the guide for your server says: Apache, Nginx.
The store finder's address comes from what is set up at Uberall. Check with Uberall that it is set up: without it, the store finder pages arrive without their stores. To use another address on this page, set it on the snippet and on the includes, as that section says.
Publish the page and the template, restart your server, and check your site.
Check
Open your store finder in a private browser window. Right click, and choose View page source. Search the source for __ubSfSsr. If you find it, it works.
Then open one of your stores and copy its address into a new tab. The store's page should open, with the store's name as the page title.
What changes on your store finder pages
On the store finder's pages, the title, the description, the canonical link, the Open Graph and twitter: tags and the structured data (application/ld+json) come from Uberall.
With the module, only what Uberall sends is replaced. What Uberall does not send for a page stays as your template has it. For example, if no description is set up at Uberall for your store finder's main page, the page keeps your template's description. A store's page also leaves out your template's links to the page in other languages (hreflang): they name the store finder page, not the store.
Through your web server, the store finder page shows only what Uberall sends.
More than one store finder
Each store finder has its own locator key and its own render token.
- a) Add a line for each key to the module's parameters, as in step a2, and put a store finder on each page, with its own settings and its own alias. Only the first store finder on a page gets its stores.
-
b) Each store finder page gets its own
<Location>orlocation, and its ownincludes with its own key. For a second token, follow "More than one store finder" in the guide for your server.
If it does not work
| What you see | What to do |
|---|---|
A store's page, such as /store-locator/l/berlin/..., says "Not Found" |
a) Check the alias in step a5, and that the page is published. b) Check step b2. |
| Add content does not list Uberall store finder | Add it to the sitemap configuration, as in step a4. |
The source has no server render (no head include in the template)
|
Add the include of step a3 to the template of the store finder page. |
The source has no server render (no token)
|
Step a2 has no token for the store finder's locator key. Check the line, or the environment variable. |
The source has no server render (no locator key on the store finder)
|
Fill in the locator key in the store finder's settings, as in step a4. |
The source has no server render (unreadable store finder address)
|
The store finder's address in step a4 is not a full address. Write it as https://www.example.com/store-locator. |
The source has no server render (declined: unauthorised)
|
The token is not the one Uberall gave you for this locator key. Paste it again. |
The source has no server render (request failed)
|
Your server cannot reach Uberall. Ask your host to allow outgoing HTTPS to uberall.com. |
The source has no server render (paused after a failure)
|
A call to Uberall failed in the last 30 seconds, so the module waits before the next one. Load the page again in a minute. |
The source still shows the include lines |
b) Includes are not on for the page: check step b2, with its Accept-Encoding line. |
The source has no server render (...) with anything else, or no __ubSfSsr
|
b) Check that your store finder's address is set up at Uberall (step b3). Then contact Uberall, with that line. |
When the store finder content does not arrive
The store finder keeps working in every case. If the content does not arrive, because your server cannot connect to Uberall, the connection takes too long or it returns an error, the page loads without it, and the store finder appears on the visitor's screen as usual.
When changes show
A change at Uberall, to your stores or to your store finder's settings, takes a few minutes to show on these pages.
With the module, OpenCms sends the store finder's pages with Cache-Control: public, max-age=0, so caches that follow it ask OpenCms again on every visit. A cache in front of OpenCms that sets its own time for your pages may keep them longer, and keep a page without its stores. If yours does, exclude the store finder's addresses, such as /store-locator/*, from it.
Through your web server, if your server or your CDN caches your pages, add the time your cache keeps them: each store finder page in that cache keeps the content it had when it was cached.