Announcement: You can find the guides for Commerce 7.5 and later on the new Elastic Path Documentation site. The Developer Center continues to support Commerce 6.13.0 through 7.4.1.Visit new site

Search Engine Optimization (SEO)

Search Engine Optimization (SEO)

Search Engine Optimization (SEO) is the process of increasing the quantity and quality of traffic to a website from search engines without having to pay for advertising. Not only does a search engine optimized website appear higher on the lists of search results, but it will also be returned by a wider variety of searches. The benefits are increased site traffic, cost savings from less advertising, more customers, and higher revenue.

Elastic Path's SEO implementation works by:

  • Generating search engine optimized URLs for Product and Category pages.
  • Displaying SEO information in HTML header blocks.
  • Parsing optimized URLs to extract content information.

Key classes and files

In Core:

  • SeoConstants - Class containing all constant values used in SEO.
  • SeoUrlBuilderImpl - Class for generating an SEO URL.
  • LocaleDependantFields - Class representing locale and SEO-related data such as title, description and keywords. Referenced by Products and Categories.

In Storefront:

  • UrlRewriteResolverImpl - Invoked by the UrlRewriteFilter to retrieve product and category UIDs from the SEO URL and set them as request attributes.
  • LocaleLinksToolsImpl - Presentation class that creates SEO urls for many locales.

In Store Assets:

  • head.vm - Velocity template that writes SEO information into the HTML head block of product and category templates.
  • VM_global_library.vm- Velocity macro library that contains methods (parseProductSeoUrl and parseCategorySeoUrl) for composing product and category SEO URLs to be used in links. The URLs are stored in the productSeoUrl and categorySeoUrl Velocity variables for use in other templates.
  • productMacro.vm - Velocity template for displaying products. Contains a map of SEO product URLs.

Third Party:

  • UrlRewriteFilter - A third-party request filter that converts SEO URLs to request attributes understood by Elastic Path
    Note:

    The SEO URL rewrite rules are stored in the COMMERCE/SYSTEM/urlRewriteConfig system setting.

Generating SEO URLs for Product and Category pages

Products and Categories contain SEO fields that are modifiable by the administrator in the Commerce Manager interface. When a customer accessing the Storefront browses the product catalog, the Velocity files acquire a map of URLs from LocaleLinksToolsImpl. If SEO is enabled, LocaleLinksToolsImpl uses the SeoUrlBuilderImpl to create SEO URLs to Products and Categories.

Parsing SEO URLs

When a customer clicks on an SEO product or category link, Elastic Path needs to translate this mostly arbitrary URL into a product or category reference. This translation is partially implemented through the use of a third-party request filter, UrlRewriteFilter, which parses the incoming SEO URL and converts string arguments to request attributes.

UrlRewriteFilter works by parsing the suffix of a URL. For example, in the following product URL:

http://localhost:8080/storefront/digital-cameras/digital-slrs/
   nikon-d50-digital-camera-slr-6-1-mpix-nikon-af-s-dx-18-
   55mm-lens-optical-zoom-3-x-supported-memory-sd/prod10030231.html

The portion of the URL between "storefront" and "prod10030231" is used by search engines and the UrlRewriteFilter ignores it when parsing the URL. It only uses the suffix prod10030231.html, which tells the system to display the product with product code 10030231.

Similarly, URLRewriteFilter interprets the following Category URL as "category 90000017, page 2":

http://localhost:8080/storefront/digital-cameras/digital-slrs/c90000017-p2.html

For more information on the rewrite filter, see http://tuckey.org/urlrewrite/.

Configuring SEO

Tip: Filtered Navigation

Filtered navigation provides additional opportunities for SEO by enabling an administrator to specify URLs that filter product lists according to specific criteria.

Constants

You can configure SEO prefixes and suffixes by changing the constants defined in the SeoConstants class. For example, by changing the Category_Prefix constant from "c" to "cat", you can change the Category URL shown above into

http://localhost:8080/storefront/digital-cameras/digital-slrs/cat90000017-p2.html
Note:

UrlRewriteFilter is configured in SeoConstants.java to apply to all URLs ending with .html.

Velocity Files

When defining SEO links in velocity files, be sure to use lower case URLs instead of camelCase.

For example, don't use <prop key="/printReceipt.ep">dummyController</prop> because search engines treat it as one word.

Instead, use <prop key="/print-receipt.ep">dummyController</prop>.

Dashes in SEO URLs

By default, the dash character (-) is used as a field separator when building SEO URLs. As a result, if you have products or categories that contain dash characters, they will not be interpreted correctly and will cause errors in the storefront. To preserve the integrity of your category and product codes in SEO URLs, you must change the field separator character to something other than the dash.

To change the field separator character:

  1. In the Commerce Manager client, edit the COMMERCE/SYSTEM/URLREWRITE/fieldSeparator system setting. This makes the SeoUrlBuilder generate URLs using the character you specify.
  2. In the Commerce Manager client, edit the XML stored in the COMMERCE/SYSTEM/urlRewriteConfig system setting. Uncomment the init-param elements and set the values to the character you want to use. This ensures Elastic Path interprets SEO URLs using the character you specify.
 
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 2.5//EN" "http://tuckey.org/res/dtds/urlrewrite2.5.dtd"> 
<!--
Configuration file for UrlRewriteFilter
http://tuckey.org/urlrewrite/
Basic SEO Configuration
========================
UrlRewriteResolverImpl takes an init-param of 'fieldSeparator', this param overrides the
default string used to tokenize the file name part of the SEO urls, this allows product
codes with dashes '-' (tokenizing default) in them to be used without changing their
codes.

If you set this param you must also set the same string in the setting property: 
COMMERCE/SYSTEM/URLREWRITE/fieldSeparator, so the urls that are generated can be parsed here.
-->
      
<urlrewrite>

    <!-- This section handles displaying SEO catalog pages in the locale
    specified in the url.
    This matches any SEO url and passes the request to UrlRewriteLocaleResolverImpl to
    determine whether the url should be redirected. This class will redirect a URL
    that contains the default locale OR a non-supported locale to the default locale URL:
    i.e. /storefront/gr/prod1234.html will redirect to /storefront/prod1234.html
    It will also set a request attribute indicating the locale which is used by other
    code in the storefront.
    -->

    <rule enabled="true">
        <name>Redirect default locale</name>
        <note>Permanently redirect to default locale (if language not defined in storefront)</note>
        <from>^/(.*)/(c|prod|sitemap)([^/]*.html[^/]*)$</from>
        <run class="com.elasticpath.sfweb.util.impl.UrlRewriteLocaleResolverImpl" method="doGet"/>
    </rule>

    <!-- This section interprets all requests for *.html pages and decodes
    the url to determine the product, catalog or sitemap to display.
    The UrlRewriteResolverImpl handles this decoding.
    -->

    <rule enabled="true">
        <!-- Category url parsing. -->
        <from>^.*/c[^/]*.html[^/]*$</from>
        <run class="com.elasticpath.sfweb.util.impl.UrlRewriteResolverImpl" method="resolve">
            <!--init-param>
                <param-name>fieldSeparator</param-name>
                <param-value>,</param-value>
            </init-param-->
        </run>
        <to>/browse.ep</to>
    </rule>

    <rule enabled="true">
        <!-- Product url parsing. -->
        <from>^.*/prod[^/]*.html[^/]*$</from>
        <run class="com.elasticpath.sfweb.util.impl.UrlRewriteResolverImpl" method="resolve">
            <!--init-param>
                <param-name>fieldSeparator</param-name>
                <param-value>,</param-value>
            </init-param-->
        </run>
        <to>/product-view.ep</to>
    </rule>

    <rule enabled="true">
        <!-- Sitemap url parsing. -->
        <from>^.*/sitemap[^/]*.html[^/]*$</from>
        <run class="com.elasticpath.sfweb.util.impl.UrlRewriteResolverImpl" method="resolve"> 
            <!--init-param>
                <param-name>fieldSeparator</param-name>
                <param-value>,</param-value>
            </init-param-->
        </run>
        <to>/sitemap.ep</to>
    </rule>

    <outbound-rule>
        <note>The outbound-rule specifies that when response.encodeURL is
        called (if you are using JSTL c:url) the url /rewrite-status
        will be rewritten to /test/status/. The above rule and this
        outbound-rule means that end users should never see the url
        /rewrite-status only /test/status/ both in thier location
        bar and in hyperlinks in your pages.</note>
        <from>/rewrite-status</from>
        <to>%{context-path}/test/status</to>
    </outbound-rule>
</urlrewrite>