Search engine optimization (SEO) is critical to boosting organic traffic to your website.

To ensure that all search engines are able to view and index your user-generated content (UGC) in all situations, implement SEO using either:

  • Schema.org markup: Client-side SEO solution (recommended)
    Note: For information about client-side SEO performance, refer to schema.org markup.
  • BVSEO: Server-side BVSEO solution. This article focuses primarily on our server-side BVSEO solution.
Caution: If your existing implementation uses the scout file (bvapi.js), refer to the BVSEO v1 documentation instead of the information included in this topic. Bazaarvoice encourages you to migrate to v2 (using the BV loader file, bv.js) for performance improvements and future innovations.

In addition to the server-side SEO solution, Bazaarvoice provides client-side JavaScript integration by default with our hosted solution and takes advantage of Google’s enhanced JavaScript indexing capabilities. If your search traffic comes largely from Google, the client-side JavaScript integration provides similar SEO benefit with less overhead. Together, the server-side and client-side SEO solutions provide outstanding SEO performance and deliver an optimized user experience.

Learn more about optimizing search:

Supported features

Bazaarvoice-managed content is injected into your pages' source code via a server-side software development kit (SDK). Here is the list of supported features for Java, .NET, and PHP.

Feature Description Java .NET PHP
Ratings & Reviews Product ratings and reviews are injected using getContent, getReviews, and getAggregateRating.
Questions & Answers Product questions and answers are injected using getContent.
Seller Ratings Seller Ratings content is accessed using getContent.
Multiple configuration support Multiple configurations are supported in a single environment.
SSL Access content using a secured layer.
Proxy support Access content using proxy gateways in a restricted network.
Debugging Troubleshooting information is available for debugging purpose.
Charset Supports user-specific character sets when retrieving content.

Setup overview

To set up BVSEO, your technical team needs to perform the following:

Compatible JavaScript for Google

User-generated content (UGC) served by Bazaarvoice takes advantage of Google's expanded JavaScript indexing performance. Understanding the following concepts can help you get more search engine optimization (SEO) benefit when using JavaScript to deploy UGC.

schema.org markup

Bazaarvoice adds correctly formed schema.org markup to UGC served to your web pages. When Google indexes this markup, the likelihood of review rich snippets appearing in search results increases.

Note: To ensure the schema.org markup is read correctly, refer to Add schema.org markup for detailed instructions.

Links between UGC content pages

When UGC content spans more than one page, Bazaarvoice uses href links between pages, allowing search engines to index the content more easily.

When shoppers view a product page that contains more than one page of reviews, they interact only with the JavaScript. The URL does not change. Bazaarvoice dynamically creates href links between pages of UGC for search indexing only, allowing search engines to point shoppers directly to relevant results.

Note: If you have an existing deployment, you might need to redeploy to production to experience this SEO benefit.

Pagination link format

Bazaarvoice appends a bvstate parameter to URLs. This parameter uses key/value pairs to define the content type and page of UGC to display. The following table lists examples of possible uses of the bvstate parameter.

Parameter text Explanation

?bvstate=pg:2/ct:r

  • Content type: Ratings & Reviews
  • Page: 2

?bvstate=pg:4/ct:q

  • Content type: Questions & Answers
  • Page: 4

Bazaarvoice adds the bvstate parameter to URLs in the canonical tag for your implementation. Consumers only encounter the bvstate parameter when following links from search results.

Note: The bvstate parameter replaces pagination parameters formerly used by Bazaarvoice such as bvrrp, bvqap, bvsyp, and bvpage. Older parameters will be phased out over time.

Prepare for SEO setup

Begin your implementation by answering questions in the following sections to help eliminate surprises and delays during setup.

Option A: Use a platform plug-in

If the website is built on Demandware, Magento, Hybris, or GSI, it is probable that a plug-in will be used to deploy BVSEO.

Option B: Use one of the BVSEO SDKs

If the website is built using Java, .NET, or PHP, BVSEO SDKs will make the SEO-friendly integration simple. Proceed to the next question to review information that should be considered prior to deployment of the BVSEO SDKs.

Option C: Develop a custom solution based on the BVSEO SDKs

If the website is built using a different technology, Ruby or Perl for example, you will need to develop a custom solution. The BVSEO SDKs are open-sourced, published in GitHub, and provide a reliable guide for those developing a custom solution. Proceed to Section 2, which is also relevant to custom solution development.

1. Will server-side coding be possible?

  • Yes – BVSEO integration requires a server-side deployment to inject search-friendly contents into the source code.
  • No – If you are unable to make server-side changes, you cannot implement the BVSEO on your site. Contact Bazaarvoice Support for information about alternate SEO resources.

2. Is a page-level cache involved? (Akamai is often used for page level caching.)

Caching may be used to improve the speed and efficiency in ways that affect the BVSEO integration. Consider the following questions related to caching.

  • Yes – If the pages where BVSEO will be implemented use a page-level cache, increase EXECUTION_TIMEOUT to 2000ms. This will ensure that SEO-friendly contents are always included in the cached version.
  • No – No additional effort.

3. Does the page use the complete URL as its cache key?

Caching may be used to improve the speed and efficiency in ways that affect the BVSEO integration. Consider the following questions related to caching.

BVSEO uses bvrrp, bvqap, bvsyp, and bvpage as URL parameters to manage pagination. http://example.com and http://example.com?bvrrp=stuff are unique pages and must be treated as unique pages by page-level caching systems.

  • Yes – No additional effort.
  • No – The cache system or URL masking system must be updated as part of the deployment.

4. Will a local cache be used to reduce server-side calls to the cloud?

BVSEO makes an HTTP or HTTPS request to seo.bazaarvoice.com (seo-stg.bazaarvoice.com for staging), which returns formatted HTML as a string. While our cloud service contains a cache for exceptionally efficient delivery (often sub 20ms), some clients opt to add an additional layer of local caching.

  • Yes – If a local cache is going to be used, Bazaarvoice recommends a maximum TTL of one hour.
  • No – No additional effort.

5. Will a proxy be needed?

BVSEO must have access to seo.bazaarvoice.com (seo-stg.bazaarvoice.com for staging) via HTTP or HTTPS. IP addresses are not available. Because BVSEO uses floating IP addresses in the cloud, we do not guarantee that IP addresses will remain consistent. If the firewall requires an IP address, a proxy must be set up to provide a consistent IP address. The SDKs contain proxy configuration options.

  • Yes – Effort will be required to set up the proxy. Use BVClientConfig.PROXY_HOST and PROXY_PORT to point the SDK at the proxy when deploying the SDK.
  • No – No additional effort.

6. Will firewall settings need to be adjusted?

BVSEO must have access to seo.bazaarvoice.com (seo-stg.bazaarvoice.com for staging) via HTTP or HTTPS. If the firewall restricts access to this address, adjustments will be needed.

  • Yes – Effort will be required to open up access.
  • No – No additional effort.

7. Will SSL connections be required?

While the content retrieved from seo.bazaarvoice.com does not contain any data that needs to be protected, security policies may require that all server-side connections are protected by SSL. SSL support is available in the Java SDK v2.1 (and above) and .NET SDK v2.1 (and above).

  • Yes – set BVClientConfig.SSL_ENABLED to true when deploying the SDK.
  • No – No additional effort.

8. Are the pages using schema.org markup?

Bazaarvoice supports both Microdata and JSON-LD formatted markup. However Google prefers JSON-LD structured markup. Bazaarvoice uses the schema.org page to guide schema markup.

9. Do the pages already contain schema.org markup?

If the page where BVSEO is being deployed contains any schema.org markup, meticulous attention to detail must be used to ensure that the schema markup does not conflict.

  • Yes - All schema.org markup must be properly nested in a single hierarchy. Carefully audit the HTML output to ensure that proper schema.org code hierarchy is present.
  • No – Refer to these instructions on how to include schema.org markup on your pages.

10. Do the pages already contain a schema.org type?

Pages must only contain one schema.org type

  • Yes – Make sure the schema.org <script> tag contains both the rating summary and reviews modules.
  • No – Add a type to the page. Bazaarvoice recommends adding schema.org/Product (Microdata format). Refer to the Java, .NET, or PHP examples for sample code.
    • Add the schema.org/Product class into a <div> tag that contains both the rating summary and reviews modules.
    • Add the product name within the schema.org/Product class using

      <div itemprop=name>[ProductName]</div> or <meta itemprop="name" content="[ProductName]" />

      Note: This applies to Microdata structured data only.

11. Do the pages have canonical tags?

If canonical tags are used on pages where BVSEO is implemented, these tags must either be updated or removed when the product contains more than one page of reviews, which is typically more than eight reviews. These canonical tags must be removed since BVSEO is paginating the product page so that all reviews are in the search engines’ index. Canonical tags that point away from a pagination URL will cause search engines to ignore the paginated content.

Note: Refer to Best practices for more information on pagination.
  • Yes – When any of the BVSEO pagination parameters are present (bvstate, bvrrp, bvqap, bvsyp, bvpage), do either of the following:

    1. Remove the canonical tag. This is the most common solution.
    2. Append the "name=value" pair to the canonical URL.
  • No – No additional effort.

Then, make sure you meet the following prerequisite conditions:

  • Verify that one of the following frameworks is installed:
    • Java framework 5 (1.5) or above
    • .NET framework 2.0 or above
    • PHP 5.5 or above with curl and Mbstring library

  • Use the Bazaarvoice hosted display, such as JavaScript or iFrame.
  • Provide a product catalog to Bazaarvoice.
  • Ensure that your product pages incorporate schema.org markup.
  • Have at least one product with reviews in the system.

During setup, you must know your BVSEO:

  • Cloud key
  • Root folders
  • Product IDs

If you do not know these values, contact Bazaarvoice Support to request the information.

Configure SEO options

Follow these steps to configure the SEO options:

  1. Sign in to the Bazaarvoice Portal .
  2. From the Portal menu, select Configuration.
  3. Select the instance.
  4. Select Go to Configuration. The Site Manager appears, listing the available deployment zones and implementations.
  5. From the Implementations list, locate the implementation where you want to configure SEO settings. Select Edit next to the implementation you want to configure.
  6. Select SEO on the left side of the page under Settings. The SEO page appears.
  7. Make selections or enter values for each of the following SEO options:
    • Enable SEO file publishing—Select Enabled (default) to publish SEO content to the cloud or compressed SEO file archive. You must also provide values for Cloud key or ZIP/GZIP filename properties.
    • Root folder—Enter the syntax to use for the name of the root folder in the cloud and/or compressed file. Use these tokens to inject dynamic properties into the filename: {clientname}, {displaycode}, {deploymentzone}, {locale}. Example: bv-acmeinc-7012-MainSite-en_US.
    • SEO-friendly pagination—Users and search engines react favorably when your site contains multiple pages for a product, and when pages after the product overview contain about 30 reviews each. Select Enabled (default) to use multiple-page settings for your product pages.
    • Cloud key—Enter your cloud key value to configure the BVSEO SDK. Be sure to include the entire value, not just the encrypted portion. If you don't have a cloud key, request one by submitting a support ticket through the Support Community .
    • schema.org/Product type—Ignore this option, which has been deprecated and is no longer used.
    • Compression type—Select the compression type for SEO feeds: ZIP (Windows) or GZIP (UNIX). If disabled, archive files will not be published to the SFTP server.
    • ZIP/GZIP filename—This option is required for compressed file publishing. Enter the syntax to use for the compressed SEO filename. Use these tokens to inject dynamic properties into the filename: {clientname}, {displaycode}, {deploymentzone}. The file extension is automatically appended based on the compression type you select. Example: bv_acmeinc_7012_MainSite-en_US.zip.
    • AggregateRating tag location—Google will only display rich snippet stars for pages with one schema.org AggregateRating tag. Choose a location from the following options to insert this tag:
      • Primary Ratings Summary (default)—Inserts the AggregateRating tag on the primary rating summary page. Bazaarvoice recommends this option.
      • Reviews Container—Inserts the AggregateRating tag at the top of the reviews container.
      • Remove Aggregate Rating tag—Excludes the AggregateRating tag.

Add code using the Java SDK

The following requirements are necessary to install the Java SDK.

  • Familiarity with Java and Java EE development and deployment to application servers
  • Java 1.6 or above
  • BVSEO SDK library for Java

Bazaarvoice follows the Oracle support levels for the JRE supported by the Java SDK. For more information, refer to the Oracle Java SE Support Roadmap .

Download the SDK

Download the appropriate Java SDK file from the following location: BVSEO Java SDK .

After you unzip the file, choose the package from the following table that best suits your environment:

Java SDK Description
Bv-seo-sdk-{version}-jar-with-dependencies.jar All dependencies are contained in the file.
Bv-seo-sdk-{version}.jar No dependencies are contained in the file.
Bv-seo-sdk-{version}-osgi.jar This SDK is for OSGi supported environments only.

If you're not sure which SDK you should use, choose one based on the following scenarios.

  • My environment supports OSGi—Use the Bv-seo-sdk-{version}-osgi.jar SDK. This is the recommended library for OSGi environments.
  • My environment does not support OSGi—Use the Bv-seo-sdk-{version}-jar-with-dependencies.jar file if there are no version conflicts caused by the SDK libraries used in your environment.
  • My environment does not support OSGi and I have version conflicts—Use bv-seo-sdk-{version}.jar file. This library does not contain any dependencies, so you must identify missing libraries and supply them manually. This can be done during compilation if there are compilation errors, or during runtime if there are "class not found" errors.

Customize the SDK

The BVSEO SDKs suit most environments. However, the BVSEO SDKs are open sourced under an Apache license and can be customized to your needs. Any customizations must be done at your own risk and will not be supported by Bazaarvoice.

Fork from the following link to perform customizations: github.com/bazaarvoice/seo_sdk_java

Set up your project

Follow these steps to set up your project.

To set up your project, configure settings in your server-side Java environment and prepare your development environment.

Configure your server environment

Note: This section applies only to clients using Java EE to deploy their site.

The Java SDK supports the collection of user agent strings, which allows us to provide user-generated content (UGC) better tailored to consumers. If your company uses Java EE to host your website, you must update your web.xml file , located in your WEB-INF folder.

Copy and paste the following text into the <web-app> element in your web.xml file:

<filter>
    <filter-name>BVSeoSdkRequestFilter</filter-name>
    <filter-class>com.bazaarvoice.seo.sdk.servlet.RequestFilter</filter-class>
</filter>
<filter-mapping> 
    <filter-name>BVSeoSdkRequestFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Configure your development environment

Follow these steps to configure your development environment. Example values for each step are provided along with example code. Refer to Java code examples for full example code for various scenarios that you can configure to your needs.

  1. Create a web project from your IDE.

    Example: sampleweb

  2. Paste the SDK library under WebContent/WEB-INF/lib.

    Example: bv-seo-sdk-{version}-jar-with-dependencies.jar

  3. Create a JSP page in the WebContent folder. Usually this JSP page will be your product detail page (PDP).

    Example: sample.jsp

  4. Set up the JSP file.

    Example: Coding sample.jsp

  5. Export the project as a WAR file and deploy to Tomcat .

    Example: The project is run from IDE, which uses Tomcat.

  6. Open the URL and view the page source to discover the injected content.

    Example: http://localhost:8080/sampleweb/sample.jsp

Your project structure should look like the following example:

Set up the JSP file

Follow these steps to set up the JSP file you created in the previous procedure.

  1. Configure using BVConfiguration.

    The example code uses BVSdkConfiguration class, which is an implementation of BVConfiguration. Ensure that com.bazaarvoice.seo.sdk.config.BVConfiguration is imported in the page and add appropriate configurations using addProperty. Refer to the BVConfiguration section of Java SDK inputs and features for details.

    The addProperty method is used to add configuration/properties to the BVSdkConfiguration and takes parameters enum type BVClientConfig and String type value. The example shows various properties already added.

  2. Set the parameters for your product detail page using BVParameters.

    This step supplies details specific to product page contents. Set parameters using the BVParameters class, which can be imported from com.bazaarvoice.seo.sdk.model.BVParameters. Be sure to include mandatory fields as shown in the Java code examples provided in this topic.

  3. Get the contents using BVManagedUIContent.

    BVUIContent has three APIs. Refer to Java SDK inputs and features for more information on each API. The example uses the getContent API and BVManagedUIContent, which is an implementation of BVUIContent. While instantiating BVManagedUIContent, supply the BVSdkConfiguration and invoke getContent passing BVParameters. This API returns a string that contains the BVSEO content, which you can use in the JSP.

Test your application

Follow these steps to test and debug your application of the Java SDK.

  1. Deploy a WAR file or use an application server such as Tomcat to run your application.
  2. Access the application via URL.

    Example: http://localhost:8080/SampleWeb/sample.jsp

  3. View the page source. Review contents and SEO <metadata> tags should appear inside the BVRRContainer.
  4. Verify that SEO metadata tags appear after every review, as shown in the following code sample:
<ul id="BVSEOSDK_meta" style="display:none !important">
    <li data-bvseo="sdk">bvseo_sdk, java_sdk, bvseo-x.y.z</li>
    <li data-bvseo="sp_mt">getContent, method:CLOUD, 188ms</li>
    <li data-bvseo="ct_st">REVIEWS, PRODUCT</li>
</ul>

If the SEO metadata tags do not match, troubleshoot and take appropriate action based on the error message in the SEO <metadata> tag.

To debug your application, complete these steps:

Step 1: Add bvreveal=debug

  1. Add the bvreveal=debug parameter to the URL of any page where BVSEO is implemented.

    Example: http://yoursite.net/ExampleGetContent.aspx?bvreveal=debug

    The bvreveal=debug parameter adds BVSEOSDK_meta and BVSEOSDK_DEBUG lists to the source code, which contain information about your implementation. If there is no user-generated content (UGC), bvseo-msg will provide more details.

    Note: If pageURL is not set up correctly, bvreveal=debug will not work. If you do not provide a debug footer, pagination links may be incorrect.
  2. View the page's source code to find information about your implementation. This information is included in BVSEOSDK_meta and BVSEOSDK_DEBUG. Refer to the full example code at the end of this section.

Step 2: Check for content

Check if content exists for the requested contentURL, as described in the following steps:

  1. Find the contentURL in the BVSEOSDK_DEBUG list. Example: <li data-bvseo="contentURL">http://seo-stg.bazaarvoice.com/myshco-69cb945801532dcfb57ad2b0d2471b68/Main_Site-en_US/reviews/product/1/5000001.htm</li>
  2. From the terminal, run the curl –i command. Example: curl –i "http://seo-stg.bazaarvoice.com/myshco-69cb945801532dcfb57ad2b0d2471b68/Main_Site-en_US/reviews/product/1/5000001.htm"

If the curl command does not return content, it could be a firewall issue or no content exists for this ProductID. Contact your Bazaarvoice representative for further troubleshooting.

Error messages

The following error messages may appear when debugging.

  • HTTP status code of 0 was returned (or) connection refused to seo-stg.bazaarvoice.com—Indicates that a firewall exists on your network. Outbound requests from your network may be blocked by your firewall. Contact your IT team to sort out firewall issues.
  • The resource to the URL or file is currently unavailable—Indicates that something is wrong with the implementation configuration or no content was generated for the specified product.

Example:

<ul id="BVSEOSDK_meta" style="display:none!important"> <li data-bvseo="sdk">bvseo_sdk, java_sdk, x.y.z</li> <li data-bvseo="sp_mt">getContent, method:CLOUD, 656ms</li> <li data-bvseo="ct_st">QUESTIONS, PRODUCT</li> <li data-bvseo="ms">bvseo-msg: The resource to the URL or file is currently unavailable.;</li> </ul> <ul id="BVSEOSDK_DEBUG" style="display:none;"> <li data-bvseo="crawlerAgentPattern">yandex</li> <li data-bvseo="staging">true</li> <li data-bvseo="seo.sdk.enabled">true</li> <li data-bvseo="testingProductionS3Hostname">seo-qa.bazaarvoice.com</li> <li data-bvseo="stagingS3Hostname">seo-stg.bazaarvoice.com</li> <li data-bvseo="seo.sdk.execution.proxy.host">none</li> <li data-bvseo="seo.sdk.execution.timeout.bot">2000</li> <li data-bvseo="socketTimeout">2000</li> <li data-bvseo="testingStagingS3Hostname">seo-qa-stg.bazaarvoice.com</li> <li data-bvseo="cloudKey">myshco-3e3001e88d9c32d19a17cafacb81bec7</li> <li data-bvseo="localSEOFileRoot">/</li> <li data-bvseo="bv.root.folder">9344</li> <li data-bvseo="seo.sdk.execution.proxy.port">0</li> <li data-bvseo="testing">false</li> <li data-bvseo="productionS3Hostname">seo.bazaarvoice.com</li> <li data-bvseo="connectTimeout">2000</li> <li data-bvseo="loadSEOFilesLocally">false</li> <li data-bvseo="seo.sdk.charset">UTF-8</li> <li data-bvseo="seo.sdk.ssl.enabled">false</li> <li data-bvseo="includeDisplayIntegrationCode">false</li> <li data-bvseo="seo.sdk.execution.timeout">1500</li> <li data-bvseo="en">true</li> <li data-bvseo="pn">bvseo-2</li> <li data-bvseo="userAgent">Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36</li> <li data-bvseo="baseURI">http://bvvseodotnetdevelopment.azurewebsites.net/ExampleGetContent.aspx</li> <li data-bvseo="pageURI">http://bvvseodotnetdevelopment.azurewebsites.net/ExampleGetContent.aspx?bvstate=pg:2/ct:q/reveal:debug</li> <li data-bvseo="subjectId">5000001</li> <li data-bvseo="contentType">questions</li> <li data-bvseo="subjectType">product</li> <li data-bvseo="contentURL">http://seo-stg.bazaarvoice.com/myshco-3e3001e88d9c32d19a17cafacb81bec7/9344/questions/product/2/5000001.htm</li> </ul>

Java SDK inputs and features

This topic provides details about the core classes in the BVSEO SDK, including configuration options and methods of use for the Java platform.

BVConfiguration

BVConfiguration configures the BVSEO SDK. It has two APIs:

  1. BVConfiguration.addProperty—Adds properties to BVConfiguration.
  2. BVConfiguration.getProperty—Gets properties from BVConfiguration.
    Note: BVConfiguration.getProperty is for Bazaarvoice internal use only.

BVConfiguration is an interface under com.bazaarvoice.seo.sdk.config and the known implementation class is com.bazaarvoice.seo.sdk.config.BVSdkConfiguration.

Java usage

BVConfiguration bvConfiguration = new BVSdkConfiguration();

Adding properties using BVConfiguration.addProperty

Adding and setting attributes in BVConfiguration changes the functionality and behavior of the SDK. Configuration options are listed in the SDK configuration attributes table.

Set attributes using BVConfiguration.addProperty (BVClientConfig bvClientConfig, String value).

Java usage

bvConfiguration.addProperty(BVClientConfig.CLOUD_KEY, “your_cloud_key”);

Attribute Type Description
CLOUD_KEY Required Cloud key string. Specifies the key used to locate the cloud SEO files. Contact Bazaarvoice to obtain the value you need for this property. This attribute is optional if LOAD_LOCAL_FILES is used.
BV_ROOT_FOLDER Required Folder path declaration. Specifies the folder where SEO files are located. This is also known as the display code. Unique root folders are created for each deployment zone and locale. Contact Bazaarvoice to obtain the value you need for this property.

SEO_SDK_ENABLED

Optional Boolean. Specifies whether to enable SEO SDK (True) or disable it (False).

Default: True
EXECUTION_TIMEOUT Optional Numeric value. Specifies the time in milliseconds (ms) to complete the SEO call for user agents and search engine bots (such as browsers) not in CRAWLER_AGENT_PATTERN.
Default: 500
EXECUTION_TIMEOUT_BOT Optional Numeric value. Specifies the time in milliseconds (ms) to complete the SEO call for search engine bots that match CRAWLER_AGENT_PATTERN.

Default: 2000
CRAWLER_AGENT_PATTERN Optional List of search engine bot user agents. Overrides the default list of search engine bot user agents. You can add and remove agents from the list. Multiple values are separated by “|”.

Default: msnbot|google|teoma|bingbot|
yandexbot|yahoo
STAGING Optional

Boolean value. Specifies whether to get SEO contents from staging (True) or from production (False) . Not applicable when using LOAD_SEO_FILES_LOCALLY.

Default: False

Note: It is common to forget to disable staging data. Check if the SDK to retrieve staging data (True) if you are not receiving content from production.
SOCKET_TIMEOUT Optional

Numeric value. Specifies atimeout for establishing connection and reading complete contents. Used internally by the SDK.

Do not modify this value unless there is a network or bandwidth issue causing frequent socket/read timeouts. This value is used for cloud SEO only and is not applicable when using LOAD_SEO_FILES_LOCALLY.

Default: 2000 ms

CONNECT_TIMEOUT Optional Numeric value. Specifies a timeout for establishing connection to cloud SEO. Used internally by the SDK. Do not modify unless necessary.

Default: 2000 ms
CHARSET Optional Character set declaration. Specifies a character set. If not specified, the default value is UTF-8. For example, use "shift_jis" when the Shift JIS character set is used.

Default: Uses the default value set by your operating system.
SSL_ENABLED Optional

Boolean value. Specifies whether or not SSL connections are required (True). Not applicable when using LOAD_SEO_FILES_LOCALLY.

Default: False

PROXY_HOST Optional Proxy host declaration. Specifies a proxy host, which is needed by some clients for security reasons. The most common use case is when firewall rules can only be set for an IP address, not a domain. Cloud SEO uses a wide range of IP addresses that are subject to change at any time, so Bazaarvoice does not provide cloud SEO IP addresses to clients. Not applicable when using LOAD_SEO_FILES_LOCALLY.
Note: To enable proxy, both PROXY_HOST and PROXY_PORT must be set.
PROXY_PORT Optional Numeric value. Specifies the port number on which the proxy/gateway system is listening. Use with PROXY_HOST.
LOAD_SEO_FILES_LOCALLY Optional (Not recommended.) Boolean value. Specifies whether to load SEO files locally (True) or not (False). Local file configurations can help overcome system limitations. A local file system can be fragile since Bazaarvoice is not responsible for the daily retrieval, unpacking, and distribution of SEO files. To enable local files, LOCAL_SEO_FILE_ROOT must be set.
LOCAL_SEO_FILE_ROOT Optional

(Not recommended.) Boolean value. Specifies whether to set the root path of the extracted SEO contents to BV_ROOT_FOLDER on the local file system (True) or not (False). Use with LOAD_SEO_FILES_LOCALLY.

BVParameters

BVParameters are the page or product display page-level parameters that access the SEO contents of a particular product. Use the attributes listed in the following SDK parameters table to set field values.

This is a model used by the SDK in the com.bazaarvoice.seo.sdk.model.BVParameters class.

Java usage

BVParameters bvParameters = new BVParameters();
bvParameters.setSubjectId(“exampleExternalId”);
bvParameters.set…

Attribute Type Description
setUserAgent Required Browser’s user-agent header information. This is used by the SDK to identify if it is a search engine bot or a normal user. This information can be retrieved from HTTPServletRequest in Java. This search engine bot is determined and matched from the configuration set by CRAWLER_AGENT_PATTERN.
setBaseURI Required URL that is used to create pagination links. Bazaarvoice will add the parameter bvstate to the base_url. In most cases, this should include the product or service page's canonical URL.

Required for product reviews. The URL can be absolute, relative, or blank (null is allowed).
setPageURI Required Sends all query parameters attached to the current URL. Bazaarvoice will use these parameters to determine which page of reviews or questions and answers content to include. You must send the full URL.
setSubjectID Required Identifier for the SEO subject to retrieve the content, which depends on the SubjectType you select. For example, if SubjectType is Product, this value is the productId. If SubjectType is Category, this value is reviewId.
setContentType Required Enum type, defined in ContentType, that retrieves SEO content. Possible values include REVIEWS, REVIEWSPAGE, QUESTIONS, QUESTIONSPAGE, and UNIVERSAL.
setSubjectType Required Enum type defined in SubjectType that retrieves content for a specific subject type. Possible values are PRODUCT, CATEGORY, ENTRY, or DETAIL.

BVUIContent

BVUIContent is used to get SEO contents after you supply the correct BVConfiguration and BVParameters.

BVUIContent exposes three APIs: getContent, getReviews, and getAggregateRating. Each of these requires valid BVParameters. The following BVUIContent APIs table explains how to use the APIs.

BVUIContent is the interface located in package com.bazaarvoice.seo.sdk. The implementation class is com.bazaarvoice.seo.sdk.BVManagedUIContent.

Java usage

BVUIContent bvUIContent = new BVManagedUIContent(bvConfiguration);
String theContent = bvUIContent.getContent(bvParameters);

API Purpose
getContent(BVParameters) Retrieves the complete content of the subject. Supported content types include REVIEWS and QUESTIONS. Content types are set inside BVParameters. Inject this content in the rating summary section of the product display page. The contents collected are injected as a single block of markup. The markup includes the main content and aggregate content, where applicable.
getReviews(BVParameters) Retrieves the reviews section and omits the aggregate section of the content type REVIEWS. This content is injected to the Review section of the product display page.
getAggregateRating(BVParameters) Retrieves the aggregate rating section of the REVIEWS content type. Inject this content in the rating summary section of the product display page.

Java code examples

The examples contained in this topic deploys the SDKs directly in the presentation layer, which simplifies the code but is not a recommended practice. The purpose of this example is to show an SDK integration. Ensure that you update your code to use correct values.

Note: All examples demonstrate integration that retrieves files using the cloud, unless otherwise specified.

This example shows Ratings & Reviews integration of BVSEO.

<%@page import="com.bazaarvoice.seo.sdk.model.ContentType"%>
<%@page import="com.bazaarvoice.seo.sdk.model.SubjectType"%>
<%@page import="com.bazaarvoice.seo.sdk.model.BVParameters"%>
<%@page import="com.bazaarvoice.seo.sdk.BVManagedUIContent"%>
<%@page import="com.bazaarvoice.seo.sdk.BVUIContent"%>
<%@page import="com.bazaarvoice.seo.sdk.config.BVClientConfig"%>
<%@page import="com.bazaarvoice.seo.sdk.config.BVSdkConfiguration"%>
<%@page import="com.bazaarvoice.seo.sdk.config.BVConfiguration"%>
<%@page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%><%

//Establish a new BVConfiguration. Properties within this configuration are typically set in bvconfig.properties.  
//addProperty can be used to override configurations set in bvconfig.properties.
BVConfiguration _bvConfig = new BVSdkConfiguration();
    _bvConfig.addProperty(BVClientConfig.CLOUD_KEY, "client-1234cloudkeygoeshere4321zxyz9876");
    _bvConfig.addProperty(BVClientConfig.BV_ROOT_FOLDER, "Main_Site-en_US"); //adjust this for each locale
    _bvConfig.addProperty(BVClientConfig.STAGING, "true");
//Prepare pageURL and SubjectID/ProductID values.       
String pageURL = request.getQueryString() == null ? request.getRequestURI() : request.getRequestURI() + "?" + request.getQueryString();
String subjectID = "ExternalId";        

//Set BV Parameters that are specific to the page and content type.
BVParameters _bvParam = new BVParameters();
    _bvParam.setBaseURI(request.getRequestURI()); // this value is used to build pagination links
    _bvParam.setPageURI(pageURL); //this value is used to extract the page number from bv URL parameters
    _bvParam.setContentType(ContentType.REVIEWS);
    _bvParam.setSubjectType(SubjectType.PRODUCT);
    _bvParam.setSubjectId(subjectID);
BVUIContent _bvOutput = new BVManagedUIContent(_bvConfig);

//Get content and place into strings, which output into the injection divs.
String sBvOutputSummary = _bvOutput.getAggregateRating(_bvParam);  //getAggregateRating delivers the AggregateRating section only
String sBvOutputReviews = _bvOutput.getReviews(_bvParam);  //getReviews delivers the review content with pagination only%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<body>
<h1>Ratings & Reviews integration of BVSEO</h1>
<h2>Using cloud for file retrieval</h2>

<div itemscope itemtype="http://schema.org/Product">
  <meta itemprop="name" content="The Amazing Wonder Ball" />
  <div data-bv-show="rating_summary" data-bv-product-id="ExternalId">
    <%=sBvOutputSummary%>
  </div>

  <div data-bv-show="reviews" data-bv-product-id="ExternalId">
    <%=sBvOutputReviews%>
  </div>
</div>

</body>
</html>

This example shows Ratings & Reviews integration of BVSEO with optional configuration parameters.

<%@page import="com.bazaarvoice.seo.sdk.model.ContentType"%>
<%@page import="com.bazaarvoice.seo.sdk.model.SubjectType"%>
<%@page import="com.bazaarvoice.seo.sdk.model.BVParameters"%>
<%@page import="com.bazaarvoice.seo.sdk.BVManagedUIContent"%>
<%@page import="com.bazaarvoice.seo.sdk.BVUIContent"%>
<%@page import="com.bazaarvoice.seo.sdk.config.BVClientConfig"%>
<%@page import="com.bazaarvoice.seo.sdk.config.BVSdkConfiguration"%>
<%@page import="com.bazaarvoice.seo.sdk.config.BVConfiguration"%>
<%@page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%><%

//Establish a new BVConfiguration. Properties within this configuration are typically set in bvconfig.properties.  
//addProperty can be used to override configurations set in bvconfig.properties.
BVConfiguration _bvConfig = new BVSdkConfiguration();
    _bvConfig.addProperty(BVClientConfig.CLOUD_KEY, "client-1234cloudkeygoeshere4321zxyz9876");
    _bvConfig.addProperty(BVClientConfig.BV_ROOT_FOLDER, "Main_Site-en_US"); //adjust this for each locale
    //optional configuration parameters
    _bvConfig.addProperty(BVClientConfig.CHARSET, "UTF-8");
       _bvConfig.addProperty(BVClientConfig.EXECUTION_TIMEOUT, "250");
    _bvConfig.addProperty(BVClientConfig.EXECUTION_TIMEOUT_BOT, "1500"); 
    _bvConfig.addProperty(BVClientConfig.CRAWLER_AGENT_PATTERN, "google|msnbot|bingbot|yandex"); //set your own bot list
    _bvConfig.addProperty(BVClientConfig.SSL_ENABLED, "false");
    _bvConfig.addProperty(BVClientConfig.STAGING, "true");

//Prepare pageURL and SubjectID/ProductID values.       
String pageURL = request.getQueryString() == null ? request.getRequestURI() : request.getRequestURI() + "?" + request.getQueryString();
String subjectID = "ExternalId";     

//Set BV Parameters that are specific to the page and content type.
BVParameters _bvParam = new BVParameters();
    _bvParam.setBaseURI(request.getRequestURI()); // this value is used to build pagination links
    _bvParam.setPageURI(pageURL); //this value is used to extract the page number from bv URL parameters
    _bvParam.setContentType(ContentType.REVIEWS);
    _bvParam.setSubjectType(SubjectType.PRODUCT);
    _bvParam.setSubjectId(subjectID);
BVUIContent _bvOutput = new BVManagedUIContent(_bvConfig);

//Get content and place into strings, which output into the injection divs.
String sBvOutputSummary = _bvOutput.getAggregateRating(_bvParam);  //getAggregateRating delivers the AggregateRating section only
String sBvOutputReviews = _bvOutput.getReviews(_bvParam);  //getReviews delivers the review content with pagination only%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<body>
<h1>Ratings & Reviews integration of BVSEO</h1>
<h2>Using cloud for file retrieval with optional configuration parameters</h2>

<div itemscope itemtype="http://schema.org/Product">
<meta itemprop="name" content="The Amazing Wonder Ball" />
  <div data-bv-show="rating_summary" data-bv-product-id="ExternalId">
    <%=sBvOutputSummary%>
  </div>

  <div data-bv-show="reviews" data-bv-product-id="ExternalId">
    <%=sBvOutputReviews%>
  </div>
</div>

</body>
</html>

This example shows Seller Ratings integration of BVSEO.

<%@page import="com.bazaarvoice.seo.sdk.model.ContentType"%>
<%@page import="com.bazaarvoice.seo.sdk.model.SubjectType"%>
<%@page import="com.bazaarvoice.seo.sdk.model.BVParameters"%>
<%@page import="com.bazaarvoice.seo.sdk.BVManagedUIContent"%>
<%@page import="com.bazaarvoice.seo.sdk.BVUIContent"%>
<%@page import="com.bazaarvoice.seo.sdk.config.BVClientConfig"%>
<%@page import="com.bazaarvoice.seo.sdk.config.BVSdkConfiguration"%>
<%@page import="com.bazaarvoice.seo.sdk.config.BVConfiguration"%>
<%@page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%
   BVConfiguration _bvConfig = new BVSdkConfiguration();
      _bvConfig.addProperty(BVClientConfig.CLOUD_KEY, "srd-testcustomer-1-c3a130de760b3105e75e8202cb22e541");
      _bvConfig.addProperty(BVClientConfig.BV_ROOT_FOLDER, "Main_Site-en_US");
   String pageURL = request.getQueryString() == null ? request.getRequestURI() : request.getRequestURI() + "?" + request.getQueryString();

   BVParameters _bvParam = new BVParameters();
      _bvParam.setUserAgent(request.getHeader( "User-Agent" ));
      _bvParam.setPageURI(pageURL);
      _bvParam.setContentType(ContentType.REVIEWS);
      // Override the default setting of PRODUCT with SELLER
      _bvParam.setSubjectType(SubjectType.SELLER);
      // Set subjectId as seller
      _bvParam.setSubjectId("seller");
   BVUIContent _bvOutput = new BVManagedUIContent(_bvConfig);

   String srdContent = _bvOutput.getContent(_bvParam);%>

<html>
<body>
   <div id="BVSellerRatingsContainer">
      <%=srdContent%>
   </div>
</body>
</html>

This example shows Ratings & Reviews integration of BVSEO using the local file system for file retrieval, instead of the cloud. Refer to Select a file method in Best Practices for more information.

<%@page import="com.bazaarvoice.seo.sdk.model.ContentType"%>
<%@page import="com.bazaarvoice.seo.sdk.model.SubjectType"%>
<%@page import="com.bazaarvoice.seo.sdk.model.BVParameters"%>
<%@page import="com.bazaarvoice.seo.sdk.BVManagedUIContent"%>
<%@page import="com.bazaarvoice.seo.sdk.BVUIContent"%>
<%@page import="com.bazaarvoice.seo.sdk.config.BVClientConfig"%>
<%@page import="com.bazaarvoice.seo.sdk.config.BVSdkConfiguration"%>
<%@page import="com.bazaarvoice.seo.sdk.config.BVConfiguration"%>
<%@page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%
//Establish a new BVConfiguration.
BVConfiguration _bvConfig = new BVSdkConfiguration();
        _bvConfig.addProperty(BVClientConfig.LOAD_SEO_FILES_LOCALLY, "true"); // set to false if using cloud-based content
        _bvConfig.addProperty(BVClientConfig.LOCAL_SEO_FILE_ROOT, "/"); //include the path to your 
        _bvConfig.addProperty(BVClientConfig.BV_ROOT_FOLDER, "Main_Site-en_US"); //adjust this for each locale
    _bvConfig.addProperty(BVClientConfig.STAGING, "true");
//Prepare pageURL and SubjectID/ProductID values.   
String pageURL = request.getQueryString() == null ? request.getRequestURI() : request.getRequestURI() + "?" + request.getQueryString();
String subjectID = "ExternalId";     

//Set BV Parameters that are specific to the page and content type.
BVParameters _bvParam = new BVParameters();
        _bvParam.setBaseURI(request.getRequestURI()); // this value is used to build pagination links
        _bvParam.setPageURI(pageURL); //this value is used to extract the page number from bv URL parameters
        _bvParam.setContentType(ContentType.REVIEWS);
        _bvParam.setSubjectType(SubjectType.PRODUCT);
        _bvParam.setSubjectId(subjectID);
BVUIContent _bvOutput = new BVManagedUIContent(_bvConfig);

//Get content and place into strings, which output into the injection divs.
String sBvOutputSummary = _bvOutput.getAggregateRating(_bvParam);  //getAggregateRating delivers the AggregateRating section only
String sBvOutputReviews = _bvOutput.getReviews(_bvParam);  //getReviews delivers the review content with pagination only
%>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<body>
<h1>Ratings & Reviews integration of BVSEO</h1>
<h2>Using local file system instead of cloud for file retrieval</h2>

<div itemscope itemtype="http://schema.org/Product">
  <meta itemprop="name" content="The Amazing Wonder Ball" />
  <div data-bv-show="rating_summary" data-bv-product-id="ExternalId">
    <%=sBvOutputSummary%>
  </div>

  <div data-bv-show="reviews" data-bv-product-id="ExternalId">
    <%=sBvOutputReviews%>
  </div>
</div>

</body>
</html>

This example shows Ratings & Reviews integration of BVSEO using a proxy.

<%@page import="com.bazaarvoice.seo.sdk.model.ContentType"%>
<%@page import="com.bazaarvoice.seo.sdk.model.SubjectType"%>
<%@page import="com.bazaarvoice.seo.sdk.model.BVParameters"%>
<%@page import="com.bazaarvoice.seo.sdk.BVManagedUIContent"%>
<%@page import="com.bazaarvoice.seo.sdk.BVUIContent"%>
<%@page import="com.bazaarvoice.seo.sdk.config.BVClientConfig"%>
<%@page import="com.bazaarvoice.seo.sdk.config.BVSdkConfiguration"%>
<%@page import="com.bazaarvoice.seo.sdk.config.BVConfiguration"%>
<%@page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>

<%
//Establish a new BVConfiguration.  
BVConfiguration _bvConfig = new BVSdkConfiguration();
    _bvConfig.addProperty(BVClientConfig.CLOUD_KEY, "client-1234cloudkeygoeshere4321zxyz9876");
    _bvConfig.addProperty(BVClientConfig.BV_ROOT_FOLDER, "Main_Site-en_US"); //adjust this for each locale
    _bvConfig.addProperty(BVClientConfig.PROXY_HOST, "00.000.000.000");
    _bvConfig.addProperty(BVClientConfig.PROXY_PORT, "80");
    _bvConfig.addProperty(BVClientConfig.STAGING, "true");
//Prepare pageURL and SubjectID/ProductID values.       
String pageURL = request.getQueryString() == null ? request.getRequestURI() : request.getRequestURI() + "?" + request.getQueryString();
String subjectID = "ExternalId";     

//Set BV Parameters that are specific to the page and content type.
BVParameters _bvParam = new BVParameters();
    _bvParam.setBaseURI(request.getRequestURI()); // this value is used to build pagination links
    _bvParam.setPageURI(pageURL); //this value is used to extract the page number from bv URL parameters
    _bvParam.setContentType(ContentType.REVIEWS);
    _bvParam.setSubjectType(SubjectType.PRODUCT);
    _bvParam.setSubjectId(subjectID);
BVUIContent _bvOutput = new BVManagedUIContent(_bvConfig);

//Get content and place into strings, which output into the injection divs.
String sBvOutputSummary = _bvOutput.getAggregateRating(_bvParam);  //getAggregateRating delivers the AggregateRating section only
String sBvOutputReviews = _bvOutput.getReviews(_bvParam);  //getReviews delivers the review content with pagination only
%>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<body>
<h1>Ratings & Reviews integration of BVSEO</h1>
<h2>Using cloud for file retrieval via a proxy</h2>

<div itemscope itemtype="http://schema.org/Product">
  <meta itemprop="name" content="The Amazing Wonder Ball" />

  <div data-bv-show="rating_summary" data-bv-product-id="ExternalId">
    <%=sBvOutputSummary%>
  </div>

  <div data-bv-show="reviews" data-bv-product-id="ExternalId">
    <%=sBvOutputReviews%>
  </div>
</div>

</body>
</html>

This example shows Ratings & Reviews and Questions & Answers integration of BVSEO.

<%@page import="com.bazaarvoice.seo.sdk.model.ContentType"%>
<%@page import="com.bazaarvoice.seo.sdk.model.SubjectType"%>
<%@page import="com.bazaarvoice.seo.sdk.model.BVParameters"%>
<%@page import="com.bazaarvoice.seo.sdk.BVManagedUIContent"%>
<%@page import="com.bazaarvoice.seo.sdk.BVUIContent"%>
<%@page import="com.bazaarvoice.seo.sdk.config.BVClientConfig"%>
<%@page import="com.bazaarvoice.seo.sdk.config.BVSdkConfiguration"%>
<%@page import="com.bazaarvoice.seo.sdk.config.BVConfiguration"%>
<%@page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>

<%
//Establish a new BVConfiguration. Properties within this configuration are typically set in bvconfig.properties.  
//addProperty can be used to override configurations set in bvconfig.properties.
BVConfiguration _bvConfig = new BVSdkConfiguration();
    _bvConfig.addProperty(BVClientConfig.CLOUD_KEY, "client-1234cloudkeygoeshere4321zxyz9876");
    _bvConfig.addProperty(BVClientConfig.BV_ROOT_FOLDER, "Main_Site-en_US"); //adjust this for each locale
    _bvConfig.addProperty(BVClientConfig.STAGING, "true");
//Prepare pageURL and SubjectID/ProductID values.       
String pageURL = request.getQueryString() == null ? request.getRequestURI() : request.getRequestURI() + "?" + request.getQueryString();
String subjectID = "ExternalId";     

//Set BV Parameters that are specific to the page and content type.
//BVParameters for Ratings & Reviews
BVParameters _bvParam = new BVParameters();
    _bvParam.setBaseURI(request.getRequestURI()); // this value is used to build pagination links
    _bvParam.setPageURI(pageURL); //this value is used to extract the page number from bv URL parameters
    _bvParam.setContentType(ContentType.REVIEWS);
    _bvParam.setSubjectType(SubjectType.PRODUCT);
    _bvParam.setSubjectId(subjectID);
BVUIContent _bvOutput = new BVManagedUIContent(_bvConfig);

//Get content and place into strings, which output into the injection divs.
String sBvOutputSummary = _bvOutput.getAggregateRating(_bvParam);  //getAggregateRating delivers the AggregateRating section only
String sBvOutputReviews = _bvOutput.getReviews(_bvParam);  //getReviews delivers the review content with pagination only

//BVQAParameters for Questions & Answers
BVParameters _bvQAParam = new BVParameters();
    _bvQAParam.setBaseURI(request.getRequestURI()); // this value is used to build pagination links
    _bvQAParam.setPageURI(pageURL); //this value is used to extract the page number from bv URL parameters
    _bvQAParam.setContentType(ContentType.QUESTIONS);
    _bvQAParam.setSubjectType(SubjectType.PRODUCT);
    _bvQAParam.setSubjectId(subjectID);
BVUIContent _bvQAOutput = new BVManagedUIContent(_bvConfig);

//Get content and place into strings, which output into the injection divs.
String sBvOutputQAContent = _bvQAOutput.getContent(_bvQAParam);  //For Questions & Answers getContent should always be used.
%>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<body>
<h1>Ratings & Reviews and Questions & Answers integration of BVSEO</h1>
<h2>Using cloud for file retrieval</h2>

<div itemscope itemtype="http://schema.org/Product">
  <meta itemprop="name" content="The Amazing Wonder Ball" />
  <div data-bv-show="rating_summary" data-bv-product-id="ExternalId">
    <%=sBvOutputSummary%>
  </div>

  <div data-bv-show="reviews" data-bv-product-id="ExternalId">
    <%=sBvOutputReviews%>
  </div>
</div>

  <div data-bv-show="questions" data-bv-product-id="ExternalId">
    <%=sBvOutputQAContent%>
  </div>
</body>
</html>

Add code using the .NET SDK

The following requirements are necessary to install the .NET SDK:

  • Familiarity with .NET development and Visual Studio IDE
  • .NET Framework 3.5 or above
  • Visual Studio
  • BVSEO SDK library for .NET

Download the SDK

Download the appropriate .NET SDK file from the following location: BVSEO .NET SDK .

The following table describes the files that are included in your download.

Filename Description
BVSeoSdkDotNet.dll BVSEO library that supports both cloud SEO and the local file method.
Commons.dll Library dependency for Apache Commons.
log4net.dll Library dependency for logging.
NVelocity.dll Library dependency for Apache NVelocity, which handles templating.
BVSeoSdkDotNet.pdb Contains debugging information.

Customize the SDK

The BVSEO SDKs suit most environments. However, the BVSEO SDKs are open sourced under an Apache license and can be customized to your needs. Any customizations must be done at your own risk and will not be supported by Bazaarvoice.

Fork from the following link to perform customizations: github.com/bazaarvoice/seo_sdk_dotnet

Set up your project

Follow these steps to set up your project. Each step includes an example value.

  1. Create an ASP.NET web application project in Visual Studio IDE, then select an empty template.

    Example: SampleWebApplication

  2. Unzip the contents from the downloaded SDK library zip file.

  3. From the Solution Explorer, expand the new project and right-click references to add the following libraries from the SDK binary: BVSeoSdkDotNet.dll, Commons.dll, log4net.dll, and NVelocity.dll.
  4. Add a new aspx page to your application. Usually this page will be your product detail page (PDP).

    Example: Sample.aspx example code

  5. Add necessary code in Sample.aspx and Sample.aspx.cs as shown in the example code.
  6. Right-click Sample.aspx and add it as a startup page.
    Note: For steps 6 and 7, ensure that SampleWebApplication is your startup project if you have more than one project in your solution.
  7. Press Crtl+F5 to run your application, or open the debug menu and select Start Without Debugging.

Set up the .NET code

Follow these steps to set up the .NET code:

  1. Configure using BVConfiguration.
  2. Set the parameters for your PDP using BVParameters.

  3. Get the contents using BVManagedUIContent.

Refer to .NET SDK inputs and features for more detailed information on each of these steps.

Refer to .NET code examples for code examples.

Test your application

Follow these steps to test and debug your application of the .NET SDK:

  1. Access the application via URL. Running your application using IDE should open up your page automatically if you have set it up as a startup page.

    Example: http://localhost:8080/Sample.aspx

  2. View the page source. Review contents and SEO <metadata> tags should appear inside the BVRRContainer.
  3. Verify that SEO <metadata> tags, as shown in the following code sample, appear after every review.
<ul id="BVSEOSDK_meta" style="display:none!important;">
    <li data-bvseo="sdk">bvseo_sdk, net_sdk, x.y.z.0</li>
    <li data-bvseo="sp_mt">getReviews, method:CLOUD, 33ms</li>
    <li data-bvseo="ct_st">REVIEWS, PRODUCT</li>
 </ul>

If the SEO <metadata> tags do not match as shown in the code sample, troubleshoot and take appropriate action based on the error message displayed in the SEO <metadata> tag.

To debug your application, complete these steps:

Step 1: Add bvreveal=debug

  1. Add the bvreveal=debug parameter to the URL of any page where BVSEO is implemented.

    Example: http://yoursite.net/ExampleGetContent.aspx?bvreveal=debug

    The bvreveal=debug parameter adds BVSEOSDK_meta and BVSEOSDK_DEBUG lists to the source code, which contain information about your implementation. If there is no user-generated content (UGC), bvseo-msg will provide more details.

    Note: If pageURL is not set up correctly, bvreveal=debug will not work. If you do not provide a debug footer, pagination links may be incorrect.
  2. View the page's source code to find information about your implementation. This information is included in BVSEOSDK_meta and BVSEOSDK_DEBUG. Refer to the full example code at the end of this section.

Step 2: Check for content

Check if content exists for the requested contentURL, as described in the following steps:

  1. Find the contentURL in the BVSEOSDK_DEBUG list. Example: <li data-bvseo="contentURL">http://seo-stg.bazaarvoice.com/myshco-69cb945801532dcfb57ad2b0d2471b68/Main_Site-en_US/reviews/product/1/5000001.htm</li>
  2. From the terminal, run the curl –i command. Example: curl –i "http://seo-stg.bazaarvoice.com/myshco-69cb945801532dcfb57ad2b0d2471b68/Main_Site-en_US/reviews/product/1/5000001.htm"

If the curl command does not return content, it could be a firewall issue or no content exists for this ProductID. Contact your Bazaarvoice representative for further troubleshooting.

Error messages

The following error messages may appear when debugging.

  • HTTP status code of 0 was returned (or) connection refused to seo-stg.bazaarvoice.com—Indicates that a firewall exists on your network. Outbound requests from your network may be blocked by your firewall. Contact your IT team to sort out firewall issues.
  • The resource to the URL or file is currently unavailable—Indicates that something is wrong with the implementation configuration or no content was generated for the specified product.

Example:

<ul id="BVSEOSDK_meta" style="display:none!important"> <li data-bvseo="sdk">bvseo_sdk, net_sdk, x.y.z.0</li> <li data-bvseo="sp_mt">getContent, method:CLOUD, 656ms</li> <li data-bvseo="ct_st">QUESTIONS, PRODUCT</li> <li data-bvseo="ms">bvseo-msg: The resource to the URL or file is currently unavailable.;</li> </ul> <ul id="BVSEOSDK_DEBUG" style="display:none;"> <li data-bvseo="crawlerAgentPattern">yandex</li> <li data-bvseo="staging">true</li> <li data-bvseo="seo.sdk.enabled">true</li> <li data-bvseo="testingProductionS3Hostname">seo-qa.bazaarvoice.com</li> <li data-bvseo="stagingS3Hostname">seo-stg.bazaarvoice.com</li> <li data-bvseo="seo.sdk.execution.proxy.host">none</li> <li data-bvseo="seo.sdk.execution.timeout.bot">2000</li> <li data-bvseo="socketTimeout">2000</li> <li data-bvseo="testingStagingS3Hostname">seo-qa-stg.bazaarvoice.com</li> <li data-bvseo="cloudKey">myshco-3e3001e88d9c32d19a17cafacb81bec7</li> <li data-bvseo="localSEOFileRoot">/</li> <li data-bvseo="bv.root.folder">9344</li> <li data-bvseo="seo.sdk.execution.proxy.port">0</li> <li data-bvseo="testing">false</li> <li data-bvseo="productionS3Hostname">seo.bazaarvoice.com</li> <li data-bvseo="connectTimeout">2000</li> <li data-bvseo="loadSEOFilesLocally">false</li> <li data-bvseo="seo.sdk.charset">UTF-8</li> <li data-bvseo="seo.sdk.ssl.enabled">false</li> <li data-bvseo="includeDisplayIntegrationCode">false</li> <li data-bvseo="seo.sdk.execution.timeout">1500</li> <li data-bvseo="en">true</li> <li data-bvseo="pn">bvseo-2</li> <li data-bvseo="userAgent">Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36</li> <li data-bvseo="baseURI">http://bvvseodotnetdevelopment.azurewebsites.net/ExampleGetContent.aspx</li> <li data-bvseo="pageURI">http://bvvseodotnetdevelopment.azurewebsites.net/ExampleGetContent.aspx?bvstate=pg:2/ct:q/reveal:debug</li> <li data-bvseo="subjectId">5000001</li> <li data-bvseo="contentType">questions</li> <li data-bvseo="subjectType">product</li> <li data-bvseo="contentURL">http://seo-stg.bazaarvoice.com/myshco-3e3001e88d9c32d19a17cafacb81bec7/9344/questions/product/2/5000001.htm</li> </ul>

.NET SDK inputs and features

This topic provides details about the core classes in the BVSEO SDK, including configuration options and methods of use for the .NET platform.

BVConfiguration

BVConfiguration configures the BVSEO SDK. It has two APIs:

  1. BVConfiguration.addProperty—Adds properties to BVConfiguration.
  2. BVConfiguration.getProperty—Gets properties from BVConfiguration.
    Note: BVConfiguration.getProperty is for Bazaarvoice internal use only.

BVSdkConfiguration is an implementation interface for BVConfiguration. Make sure to add using BVSeoSdkDotNet.Config.

.NET usage

BVConfiguration bvConfig = new BVSdkConfiguration();

Adding properties

Adding and setting attributes in BVConfiguration changes the functionality and behavior of the SDK. Configuration options are listed in the following SDK configuration attributes table.

Set these attributes using the addProperty method on BVConfiguration.

.NET usage: bvConfig.addProperty(BVClientConfig.CLOUD_KEY, “your_cloud_key”);

SDK configuration attributes table

Attribute Type Description
CLOUD_KEY Required Cloud key string. Specifies the key used to locate the cloud SEO files. Contact Bazaarvoice to obtain the value you need for this property. This attribute is optional if LOAD_LOCAL_FILES is used.
BV_ROOT_FOLDER Required Folder path declaration. Specifies the folder where SEO files are located. This is also known as the display code. Unique root folders are created for each deployment zone and locale. Contact Bazaarvoice to obtain the value you need for this property.

SEO_SDK_ENABLED

Optional Boolean. Specifies whether to enable SEO SDK (True) or disable it (False).

Default: True
EXECUTION_TIMEOUT Optional Numeric value. Specifies the time in milliseconds (ms) to complete the SEO call for user agents and search engine bots (such as browsers) not in CRAWLER_AGENT_PATTERN.
Default: 500
EXECUTION_TIMEOUT_BOT Optional Numeric value. Specifies the time in milliseconds (ms) to complete the SEO call for search engine bots that match CRAWLER_AGENT_PATTERN.

Default: 2000
CRAWLER_AGENT_PATTERN Optional List of search engine bot user agents. Overrides the default list of search engine bot user agents. You can add and remove agents from the list. Multiple values are separated by “|”.

Default: msnbot|google|teoma|bingbot|
yandexbot|yahoo
STAGING Optional

Boolean value. Specifies whether to get SEO contents from staging (True) or from production (False) . Not applicable when using LOAD_SEO_FILES_LOCALLY.

Default: False

Note: It is common to forget to disable staging data. Check if the SDK to retrieve staging data (True) if you are not receiving content from production.
SOCKET_TIMEOUT Optional

Numeric value. Specifies atimeout for establishing connection and reading complete contents. Used internally by the SDK.

Do not modify this value unless there is a network or bandwidth issue causing frequent socket/read timeouts. This value is used for cloud SEO only and is not applicable when using LOAD_SEO_FILES_LOCALLY.

Default: 2000 ms

CONNECT_TIMEOUT Optional Numeric value. Specifies a timeout for establishing connection to cloud SEO. Used internally by the SDK. Do not modify unless necessary.

Default: 2000 ms
CHARSET Optional Character set declaration. Specifies a character set. If not specified, the default value is UTF-8. For example, use "shift_jis" when the Shift JIS character set is used.

Default: Uses the default value set by your operating system.
SSL_ENABLED Optional

Boolean value. Specifies whether or not SSL connections are required (True). Not applicable when using LOAD_SEO_FILES_LOCALLY.

Default: False

PROXY_HOST Optional Proxy host declaration. Specifies a proxy host, which is needed by some clients for security reasons. The most common use case is when firewall rules can only be set for an IP address, not a domain. Cloud SEO uses a wide range of IP addresses that are subject to change at any time, so Bazaarvoice does not provide cloud SEO IP addresses to clients. Not applicable when using LOAD_SEO_FILES_LOCALLY.
Note: To enable proxy, both PROXY_HOST and PROXY_PORT must be set.
PROXY_PORT Optional Numeric value. Specifies the port number on which the proxy/gateway system is listening. Use with PROXY_HOST.
LOAD_SEO_FILES_LOCALLY Optional (Not recommended.) Boolean value. Specifies whether to load SEO files locally (True) or not (False). Local file configurations can help overcome system limitations. A local file system can be fragile since Bazaarvoice is not responsible for the daily retrieval, unpacking, and distribution of SEO files. To enable local files, LOCAL_SEO_FILE_ROOT must be set.
LOCAL_SEO_FILE_ROOT Optional

(Not recommended.) Boolean value. Specifies whether to set the root path of the extracted SEO contents to BV_ROOT_FOLDER on the local file system (True) or not (False). Use with LOAD_SEO_FILES_LOCALLY.

BVParameters

BVParameters are the page or product display page-level parameters that access the SEO contents of a particular product. Use the attributes listed in the following SDK parameters table to set field values.

This is a model used by the SDK that is added using BVSeoSdkDotNet.Model

.NET usage

BVParameters bvParameters = new BVParameters
{
BaseURI = <baseURI>,

SubjectId = “exampleExternalId”
};

Or

BVParameters bvParameters = new BVParameters();
bvParameters.SubjectId = “exampleExternalId”

SDK parameters

Attribute Type Description
setUserAgent Required Browser’s user-agent header information. This is used by the SDK to identify if it is a search engine bot or a normal user. This information can be retrieved from HTTPServletRequest in Java. This search engine bot is determined and matched from the configuration set by CRAWLER_AGENT_PATTERN.
setBaseURI Required URL that is used to create pagination links. Bazaarvoice will add the parameter bvstate to the base_url. In most cases, this should include the product or service page's canonical URL.

Required for product reviews. The URL can be absolute, relative, or blank (null is allowed).
setPageURI Required Sends all query parameters attached to the current URL. Bazaarvoice will use these parameters to determine which page of reviews or questions and answers content to include. You must send the full URL.
setSubjectID Required Identifier for the SEO subject to retrieve the content, which depends on the SubjectType you select. For example, if SubjectType is Product, this value is the productId. If SubjectType is Category, this value is reviewId.
setContentType Required Enum type, defined in ContentType, that retrieves SEO content. Possible values include REVIEWS, REVIEWSPAGE, QUESTIONS, QUESTIONSPAGE, and UNIVERSAL.
setSubjectType Required Enum type defined in SubjectType that retrieves content for a specific subject type. Possible values are PRODUCT, CATEGORY, ENTRY, or DETAIL.

BVUIContent

BVUIContent is used to get SEO contents after you supply the correct BVConfiguration and BVParameters.

BVUIContent exposes three APIs: getContent, getReviews, and getAggregateRating. Each of these requires valid BVParameters. The following BVUIContent APIs table explains how to use the APIs.

BVManagedUIContent is an implementation for BVUIContent and is added using BVSeoSdkDotNet.Content.

.NET usage

BVUIContent bvUIContent = new BVManagedUIContent(bvConfig);

string theContent = bvUIContent.getContent(bvParameters);

BVUIContent API

API Purpose
getContent(BVParameters) Retrieves the complete content of the subject. Supported content types include REVIEWS and QUESTIONS. Content types are set inside BVParameters. Inject this content in the rating summary section of the product display page. The contents collected are injected as a single block of markup. The markup includes the main content and aggregate content, where applicable.
getReviews(BVParameters) Retrieves the reviews section and omits the aggregate section of the content type REVIEWS. This content is injected to the Review section of the product display page.
getAggregateRating(BVParameters) Retrieves the aggregate rating section of the REVIEWS content type. Inject this content in the rating summary section of the product display page.

.NET code examples

The examples contained in this topic deploy the SDK directly on an empty ASP.NET project with ASPX webform code behind a page, which simplifies the code but is not a recommended practice. The purpose of these examples is to show how an SDK integration is done. Ensure that you update your code to use proper values.

Note: If you are using a Web Site project, be sure to switch the CodeBehind page directive to CodeFile before copying the examples.

Sample.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Sample.aspx.cs" Inherits="SampleWebApplication.Sample" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>Sample SDK Implementation</title></head>
<body>
   <div id="SEO_BVRRSummaryContainer" runat="sever" data-bv-show="rating_summary" data-bv-product-id="ExternalId"></div> 
  <div id="SEO_BVRRContainer" runat="sever" data-bv-show="reviews" data-bv-product-id="ExternalId"></div>
</body>
</html>

Sample.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using BVSeoSdkDotNet.Config;
using BVSeoSdkDotNet.Content;
using BVSeoSdkDotNet.Model;

namespace SampleWebApplication
{
   public partial class Sample : System.Web.UI.Page
   {
      protected void Page_Load(object sender, EventArgs e)
      {

         BVConfiguration bvConfig = new BVSdkConfiguration();

         String cloudKey = Request.QueryString["cloudkey"];
         String staging = Request.QueryString["staging"];
         String testing = Request.QueryString["testing"];
         String rootFolder = Request.QueryString["site"];
         String productIdParam = Request.QueryString["productid"];

         String subjectId = "5000001";

         if (cloudKey != null)
         bvConfig.addProperty(BVClientConfig.CLOUD_KEY, cloudKey);
         else
         bvConfig.addProperty(BVClientConfig.CLOUD_KEY, "myshco-3e3001e88d9c32d19a17cafacb81bec7");
         if (staging != null)
         bvConfig.addProperty(BVClientConfig.STAGING, staging);
         else
         bvConfig.addProperty(BVClientConfig.STAGING, "true");
         if (testing != null)
         bvConfig.addProperty(BVClientConfig.TESTING, testing);
         else
         bvConfig.addProperty(BVClientConfig.TESTING, "false");

         if (rootFolder != null)
         bvConfig.addProperty(BVClientConfig.BV_ROOT_FOLDER, rootFolder);
         else
         bvConfig.addProperty(BVClientConfig.BV_ROOT_FOLDER, "9344");

         if (productIdParam != null)
         {
            //if productIdParameter is null then use the default value.  If it's not null then use the parameter.  If category
            subjectId = productIdParam;
         }
         else
         subjectId = "5000001";

         bvConfig.addProperty(BVClientConfig.SEO_SDK_ENABLED, "true");  // use this as a kill switch
         bvConfig.addProperty(BVClientConfig.LOAD_SEO_FILES_LOCALLY, "false"); // set to false if using cloud-based content
         bvConfig.addProperty(BVClientConfig.LOCAL_SEO_FILE_ROOT, "/");

         bvConfig.addProperty(BVClientConfig.CRAWLER_AGENT_PATTERN, "yandex");

         bvConfig.addProperty(BVClientConfig.EXECUTION_TIMEOUT, "1500");
         bvConfig.addProperty(BVClientConfig.EXECUTION_TIMEOUT_BOT, "2000");

         var bvParameters = new BVParameters
         {
            BaseURI =
            Request.Url.ToString().Contains("?")
            ? Request.Url.ToString().Substring(0, Request.Url.ToString().IndexOf("?"))
            : Request.Url.ToString(),
            PageURI = Request.Url.ToString(),
            ContentType = new BVContentType(BVContentType.REVIEWS),
            SubjectType = new BVSubjectType(BVSubjectType.PRODUCT),
            SubjectId = subjectId
         };

         BVUIContent bvOutput = new BVManagedUIContent(bvConfig);
         SEO_BVRRSummaryContainer.InnerHtml = bvOutput.getAggregateRating(bvParameters);
         SEO_BVRRContainer.InnerHtml = bvOutput.getReviews(bvParameters);
      }
   }
}

This example shows Ratings & Reviews integration of BVSEO.

using System;
using BVSeoSdkDotNet.Config;
using BVSeoSdkDotNet.Content;
using BVSeoSdkDotNet.Model;
using BVSeoSdkDotNet.BVException;

namespace Aspx_Examples
{
    public partial class ex_simple_rr_cloud : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            //Establish a new BVConfiguration. Properties within this configuration are typically set in bvconfig.properties.  
            //addProperty can be used to override configurations set in bvconfig.properties.
            BVConfiguration bvConfig = new BVSdkConfiguration();
            bvConfig.addProperty(BVClientConfig.CLOUD_KEY, "client-1234cloudkeygoeshere4321zxyz9876");
            bvConfig.addProperty(BVClientConfig.BV_ROOT_FOLDER, "Main_Site-en_US"); //adjust this for each locale
            bvConfig.addProperty(BVClientConfig.STAGING, "true");

            //Prepare pageURL and SubjectID/ProductID values.   
            String subjectID = "ExternalId";
            String pageURL = Request.Url.ToString();

            //Set BV Parameters that are specific to the page and content type.
            BVParameters bvParam = new BVParameters();
            bvParam.BaseURI = pageURL.Contains("?") ? pageURL.Substring(0, pageURL.IndexOf("?")) : pageURL;
            bvParam.PageURI = Request.Url.ToString(); //this value is used to extract the page number from bv URL parameters
            bvParam.ContentType = new BVContentType(BVContentType.REVIEWS);
            bvParam.SubjectType = new BVSubjectType(BVSubjectType.PRODUCT);
            bvParam.SubjectId = subjectID;

            //Get content and place into strings, then output into the injection divs.
            BVUIContent bvOutput = new BVManagedUIContent(bvConfig);
            String sBvOutputSummary = bvOutput.getAggregateRating(bvParam);  //getAggregateRating delivers the AggregateRating section only
            String sBvOutputReviews = bvOutput.getReviews(bvParam);  //getReviews delivers the review content with pagination only
            SEO_BVRRSummaryContainer.InnerHtml = sBvOutputSummary;
            SEO_BVRRContainer.InnerHtml = sBvOutputReviews;
        }
    }
}

You can also use the following HTML code snippet.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ex-simple-rr-cloud.aspx.cs" Inherits="Aspx_Examples.ex_simple_rr_cloud" %>

<!DOCTYPE html>
<head runat="server">
    <title></title>
</head>
<body>
    <h1>Reviews Integration of BVSEO</h1>
    <h2>using cloud for file retrieval</h2>

    <div itemscope itemtype="http://schema.org/Product">
        <meta itemprop="name" content="The Amazing Wonder Ball" />
        <div id="SEO_BVRRSummaryContainer" runat="sever" data-bv-show="rating_summary" data-bv-product-id="ExternalId"></div>        
        <div id="SEO_BVRRContainer" runat="sever" data-bv-show="reviews" data-bv-product-id="ExternalId"></div>
    </div>
</body>

This example shows Ratings & Reviews integration of BVSEO with optional configuration parameters.

using System;
using BVSeoSdkDotNet.Config;
using BVSeoSdkDotNet.Content;
using BVSeoSdkDotNet.Model;
using BVSeoSdkDotNet.BVException;

namespace Aspx_Examples
{
    public partial class ex_expanded_rr_cloud : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            //Establish a new BVConfiguration. Properties within this configuration are typically set in bvconfig.properties.  
            //addProperty can be used to override configurations set in bvconfig.properties.
            BVConfiguration bvConfig = new BVSdkConfiguration();
            bvConfig.addProperty(BVClientConfig.CLOUD_KEY, "client-1234cloudkeygoeshere4321zxyz9876");
            bvConfig.addProperty(BVClientConfig.BV_ROOT_FOLDER, "Main_Site-en_US"); //adjust this for each locale

            //optional configuration parameters
            bvConfig.addProperty(BVClientConfig.CHARSET, "UTF-8");
            bvConfig.addProperty(BVClientConfig.EXECUTION_TIMEOUT, "250");
         bvConfig.addProperty(BVClientConfig.EXECUTION_TIMEOUT_BOT, "1500");
         bvConfig.addProperty(BVClientConfig.CRAWLER_AGENT_PATTERN, "google|msnbot|bingbot|yandex"); //set your own bot list;
            bvConfig.addProperty(BVClientConfig.SSL_ENABLED, "false");
            bvConfig.addProperty(BVClientConfig.STAGING, "true");

            //Prepare pageURL and SubjectID/ProductID values.   
            String subjectID = "ExternalId";
            String pageURL = Request.Url.ToString();

            //Set BV Parameters that are specific to the page and content type.
            BVParameters bvParam = new BVParameters();
            bvParam.BaseURI = pageURL.Contains("?") ? pageURL.Substring(0, pageURL.IndexOf("?")) : pageURL;
            bvParam.PageURI = Request.Url.ToString(); //this value is used to extract the page number from bv URL parameters
            bvParam.ContentType = new BVContentType(BVContentType.REVIEWS);
            bvParam.SubjectType = new BVSubjectType(BVSubjectType.PRODUCT);
            bvParam.SubjectId = subjectID;

            //Get content and place into strings, then output into the injection divs.
            BVUIContent bvOutput = new BVManagedUIContent(bvConfig);
            String outputSummary = bvOutput.getAggregateRating(bvParam);    //getAggregateRating delivers the AggregateRating section only
            String outputReviews = bvOutput.getReviews(bvParam);     //getReviews delivers the review content with pagination only
            SEO_BVRRSummaryContainer.InnerHtml = outputSummary;
            SEO_BVRRContainer.InnerHtml = outputReviews;
        }
    }
}

You can also use the following HTML code snippet.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ex-expanded-rr-cloud.aspx.cs" Inherits="Aspx_Examples.ex_expanded_rr_cloud" %>

<!DOCTYPE html>
<head runat="server">
    <title></title>
</head>
<body>
    <h1>Reviews Integration of BVSEO</h1>
    <h2>using cloud for file retrieval with optional configuration parameters</h2>

    <div itemscope itemtype="http://schema.org/Product">
        <meta itemprop="name" content="The Amazing Wonder Ball" />
        <div id="SEO_BVRRSummaryContainer" runat="sever" data-bv-show="rating_summary" data-bv-product-id="ExternalId"></div>       
        <div id="SEO_BVRRContainer" runat="sever" data-bv-show="reviews" data-bv-product-id="ExternalId"></div>
    </div>
</body>

This example shows Seller Ratings integration of BVSEO.

using System;
using BVSeoSdkDotNet.Config;
using BVSeoSdkDotNet.Content;
using BVSeoSdkDotNet.Model;

namespace DotNetAspxExample
{
   public partial class ExampleGetSellerRatings : System.Web.UI.Page
   {
      protected void Page_Load(object sender, EventArgs e)
      {
         BVConfiguration bvConfig = new BVSdkConfiguration();
         String cloudKey = Request.QueryString["cloudkey"];
         String staging = Request.QueryString["staging"];
         String testing = Request.QueryString["testing"];
         String rootFolder = Request.QueryString["site"];
         String subjectId = "seller";

         if (cloudKey != null)
         {
            bvConfig.addProperty(BVClientConfig.CLOUD_KEY, cloudKey);
         }
         else
         {
            bvConfig.addProperty(BVClientConfig.CLOUD_KEY, "srd-testcustomer-1-c3a130de760b3105e75e8202cb22e541");
         }
         if (staging != null)
         {
            bvConfig.addProperty(BVClientConfig.STAGING, staging);
         }
         else
         {
            bvConfig.addProperty(BVClientConfig.STAGING, "false");
         }
         if (testing != null)
         {
            bvConfig.addProperty(BVClientConfig.TESTING, testing);
         }
         else
         {
            bvConfig.addProperty(BVClientConfig.TESTING, "true");
         }

         if (rootFolder != null)
         {
            bvConfig.addProperty(BVClientConfig.BV_ROOT_FOLDER, rootFolder);
         }
         else
         {
            bvConfig.addProperty(BVClientConfig.BV_ROOT_FOLDER, "Main_Site-en_US");
         }

         var bvParameters = new BVParameters
         {
            BaseURI =
               Request.Url.ToString().Contains("?")
                  ? Request.Url.ToString().Substring(0, Request.Url.ToString().IndexOf("?"))
                  : Request.Url.ToString(),
            PageURI = Request.Url.ToString(),
            ContentType = new BVContentType(BVContentType.REVIEWS),
            SubjectType = new BVSubjectType(BVSubjectType.SELLER),
            SubjectId = subjectId
         };

         BVUIContent bvOutput = new BVManagedUIContent(bvConfig);
         BVSellerRatingsContainer.InnerHtml = bvOutput.getContent(bvParameters);
         BVSEOURL.InnerHtml = bvOutput.getUrl();
      }
   }
}

You can also use the following HTML code snippet.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ex_simple_srd.aspx.cs" Inherits="Aspx_Examples.ex_simple_srd" %>

<!DOCTYPE html>
<head runat="server">
   <title></title>
</head>
<body>
   <h1>SellerRatingsDisplay Integration</h1>
   <div>
      <div id="BVSellerRatingsContainer" runat="server"></div>
   </div>
</body>

This example shows Ratings & Reviews integration of BVSEO using the local file system for file retrieval, instead of the cloud. Refer to Select a file method for more information.

using System;
using BVSeoSdkDotNet.Config;
using BVSeoSdkDotNet.Content;
using BVSeoSdkDotNet.Model;
using BVSeoSdkDotNet.BVException;

namespace Aspx_Examples
{
    public partial class ex_simple_rr_local_file : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            //Establish a new BVConfiguration.
            BVConfiguration bvConfig = new BVSdkConfiguration();
            bvConfig.addProperty(BVClientConfig.LOAD_SEO_FILES_LOCALLY, "true"); // set to false if using cloud-based content
            bvConfig.addProperty(BVClientConfig.LOCAL_SEO_FILE_ROOT, "/path/to/your/zipped/seo/file"); //include the path to your 
            bvConfig.addProperty(BVClientConfig.BV_ROOT_FOLDER, "Main_Site-en_US"); //adjust this for each locale

            //Prepare pageURL and SubjectID/ProductID values.   
            String subjectID = "ExternalId";
            String pageURL = Request.Url.ToString();

            //Set BV Parameters that are specific to the page and content type.
            BVParameters bvParam = new BVParameters();
            bvParam.BaseURI = pageURL.Contains("?") ? pageURL.Substring(0, pageURL.IndexOf("?")) : pageURL;
            bvParam.PageURI = Request.Url.ToString(); //this value is used to extract the page number from bv URL parameters
            bvParam.ContentType = new BVContentType(BVContentType.REVIEWS);
            bvParam.SubjectType = new BVSubjectType(BVSubjectType.PRODUCT);
            bvParam.SubjectId = subjectID;

            //Get content and place into strings, then output into the injection divs.
            BVUIContent bvOutput = new BVManagedUIContent(bvConfig);
            String sBvOutputSummary = bvOutput.getAggregateRating(bvParam);  //getAggregateRating delivers the AggregateRating section only
            String sBvOutputReviews = bvOutput.getReviews(bvParam);  //getReviews delivers the review content with pagination only
            SEO_BVRRSummaryContainer.InnerHtml = sBvOutputSummary;
            SEO_BVRRContainer.InnerHtml = sBvOutputReviews;
        }
    }
}

You can also use the following HTML code snippet.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ex-simple-rr-local-file.aspx.cs" Inherits="Aspx_Examples.ex_simple_rr_local_file" %>

<!DOCTYPE html>
<head runat="server">
    <title></title>
</head>
<body>
    <h1>Reviews Integration of BVSEO</h1>
    <h2>using local file system instead of cloud for file retrieval</h2>

    <div itemscope itemtype="http://schema.org/Product">
        <meta itemprop="name" content="The Amazing Wonder Ball" />
        <div id="SEO_BVRRSummaryContainer" runat="sever" data-bv-show="rating_summary" data-bv-product-id="ExternalId"></div>      
        <div id="SEO_BVRRContainer" runat="sever" data-bv-show="reviews" data-bv-product-id="ExternalId"></div>
    </div>
</body>

This example shows Ratings & Reviews integration of BVSEO using a proxy.

using System;
using BVSeoSdkDotNet.Config;
using BVSeoSdkDotNet.Content;
using BVSeoSdkDotNet.Model;
using BVSeoSdkDotNet.BVException;

namespace Aspx_Examples
{
    public partial class ex_simple_rr_cloud_proxy : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            //Establish a new BVConfiguration.  
            BVConfiguration bvConfig = new BVSdkConfiguration();
            bvConfig.addProperty(BVClientConfig.CLOUD_KEY, "client-1234cloudkeygoeshere4321zxyz9876");
            bvConfig.addProperty(BVClientConfig.BV_ROOT_FOLDER, "Main_Site-en_US"); //adjust this for each locale
            bvConfig.addProperty(BVClientConfig.STAGING, "true");
            bvConfig.addProperty(BVClientConfig.PROXY_HOST, "00.000.000.000");
            bvConfig.addProperty(BVClientConfig.PROXY_PORT, "80");

            //Prepare pageURL and SubjectID/ProductID values.   
            String subjectID = "ExternalId";
            String pageURL = Request.Url.ToString();

            //Set BV Parameters that are specific to the page and content type.
            BVParameters bvParam = new BVParameters();
            bvParam.BaseURI = pageURL.Contains("?") ? pageURL.Substring(0, pageURL.IndexOf("?")) : pageURL;
            bvParam.PageURI = Request.Url.ToString(); //this value is used to extract the page number from bv URL parameters
            bvParam.ContentType = new BVContentType(BVContentType.REVIEWS);
            bvParam.SubjectType = new BVSubjectType(BVSubjectType.PRODUCT);
            bvParam.SubjectId = subjectID;

            //Get content and place into strings, then output into the injection divs.
            BVUIContent bvOutput = new BVManagedUIContent(bvConfig);
            String sBvOutputSummary = bvOutput.getAggregateRating(bvParam);  //getAggregateRating delivers the AggregateRating section only
            String sBvOutputReviews = bvOutput.getReviews(bvParam);  //getReviews delivers the review content with pagination only
            SEO_BVRRSummaryContainer.InnerHtml = sBvOutputSummary;
            SEO_BVRRContainer.InnerHtml = sBvOutputReviews;
        }
    }
}

You can also use the following HTML code snippet.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ex-simple-rr-cloud-proxy.aspx.cs" Inherits="Aspx_Examples.ex_simple_rr_cloud_proxy" %>

<!DOCTYPE html>
<head runat="server">
    <title></title>
</head>
<body>
    <h1>Reviews Integration of BVSEO</h1>
    <h2>using cloud for file retrieval via a proxy</h2>

   <div itemscope itemtype="http://schema.org/Product">
        <meta itemprop="name" content="The Amazing Wonder Ball" />
        <div id="SEO_BVRRSummaryContainer" runat="sever" data-bv-show="rating_summary" data-bv-product-id="ExternalId"></div>
        <div id="SEO_BVRRContainer" runat="sever" data-bv-show="reviews" data-bv-product-id="ExternalId"></div>
    </div>
</body>

This example shows Ratings & Reviews and Questions & Answers integration of BVSEO.

using System;
using BVSeoSdkDotNet.Config;
using BVSeoSdkDotNet.Content;
using BVSeoSdkDotNet.Model;
using BVSeoSdkDotNet.BVException;

namespace Aspx_Examples
{
    public partial class ex_simple_rr_qa_cloud : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            //Establish a new BVConfiguration. Properties within this configuration are typically set in bvconfig.properties.  
            //addProperty can be used to override configurations set in bvconfig.properties.
            BVConfiguration bvConfig = new BVSdkConfiguration();
            bvConfig.addProperty(BVClientConfig.CLOUD_KEY, "client-1234cloudkeygoeshere4321zxyz9876");
            bvConfig.addProperty(BVClientConfig.BV_ROOT_FOLDER, "Main_Site-en_US"); //adjust this for each locale
            bvConfig.addProperty(BVClientConfig.STAGING, "true");

            //Prepare pageURL and SubjectID/ProductID values.   
            String subjectID = "ExternalId";
            String pageURL = Request.Url.ToString();

            //Set BV Parameters that are specific to the page and content type.
            //BVParameters for Ratings & Reviews
            BVParameters bvParam = new BVParameters();
            bvParam.BaseURI = pageURL.Contains("?") ? pageURL.Substring(0, pageURL.IndexOf("?")) : pageURL;
            bvParam.PageURI = Request.Url.ToString(); //this value is used to extract the page number from bv URL parameters
            bvParam.ContentType = new BVContentType(BVContentType.REVIEWS);
            bvParam.SubjectType = new BVSubjectType(BVSubjectType.PRODUCT);
            bvParam.SubjectId = subjectID;
            BVUIContent bvOutput = new BVManagedUIContent(bvConfig);

            //Get content and place into strings, then output into the injection divs.
            String sBvOutputSummary = bvOutput.getAggregateRating(bvParam);  //getAggregateRating delivers the AggregateRating section only
            String sBvOutputReviews = bvOutput.getReviews(bvParam);  //getReviews delivers the review content with pagination only
            SEO_BVRRSummaryContainer.InnerHtml = sBvOutputSummary;
            SEO_BVRRContainer.InnerHtml = sBvOutputReviews;

            //BVQAParameters for Questions & Answers
            BVParameters bvQAParam = new BVParameters();
            bvQAParam.BaseURI = pageURL.Contains("?") ? pageURL.Substring(0, pageURL.IndexOf("?")) : pageURL;
            bvQAParam.PageURI = Request.Url.ToString(); //this value is used to extract the page number from bv URL parameters
            bvQAParam.ContentType = new BVContentType(BVContentType.QUESTIONS);
            bvQAParam.SubjectType = new BVSubjectType(BVSubjectType.PRODUCT);
            bvQAParam.SubjectId = subjectID;
            BVUIContent bvQAOutput = new BVManagedUIContent(bvConfig);

            //Get content and place into strings, then output into the injection divs.
            String sBvOutputQAContent = bvQAOutput.getContent(bvQAParam);  //For Questions & Answers getContent should always be used.
            SEO_BVQAContainer.InnerHtml = sBvOutputQAContent;
        }
    }
}

You can also use the following HTML code snippet.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ex-simple-rr-qa-cloud.aspx.cs" Inherits="Aspx_Examples.ex_simple_rr_qa_cloud" %>

<!DOCTYPE html>
<head runat="server">
    <title></title>
</head>
<body>
    <h1>Reviews and Question/Answers Integration of BVSEO</h1>
    <h2>using cloud for file retrieval</h2>

    <div itemscope itemtype="http://schema.org/Product">
        <meta itemprop="name" content="The Amazing Wonder Ball" />
        <div id="SEO_BVRRSummaryContainer" runat="sever" data-bv-show="rating_summary" data-bv-product-id="ExternalId"></div>        
        <div id="SEO_BVRRContainer" runat="sever" data-bv-show="reviews" data-bv-product-id="ExternalId"></div>
    </div>

    <div id="SEO_BVQAContainer" runat="sever" data-bv-show="questions" data-bv-product-id="ExternalId"></div>
</body>

Add code using the PHP SDK

The following requirements are necessary to install the PHP SDK:

  • HTTP server or PHP built-in web server
  • PHP 5.5 or higher with curl and mbstring library

  • BVSEO SDK library for PHP
Note: Bazaarvoice supports only the current PHP versions as listed on the php.net supported versions page.

Download the SDK

Download the appropriate PHP SDK file from the following location: BVSEO PHP SDK .

The following files are included in the download.

Filename Description
Bvseosdk.php BVSEO library that supports both cloud SEO and the local file method.
BVFooter.php Used to generate content and debug the SDK footer.
BVUtility.php Common utility functions used by the BVSEO SDK library.

Customize the SDK

The BVSEO SDKs suit most environments. However, the BVSEO SDKs are open sourced under an Apache license and can be customized to your needs. Any customizations must be done at your own risk and will not be supported by Bazaarvoice.

Fork from the following link to perform customizations: github.com/bazaarvoice/seo_sdk_php

Set up your project

Follow these steps to set up your project. Example values for each step are provided, along with example code. Refer to PHP code examples for full example code for various scenarios that you can configure to your needs.

  1. Create a file.

    Example: sampleweb.php

  2. Include the bvseosdk.php.
  3. Instantiate the bv object.
  4. Call $bv->reviews->getReviews() inside <div data-bv-show="reviews" data-bv-product-id="ExternalId"></div> to get the BVSEO content. This call will return the BVSEO HTML code as a string.

Test your application

Follow these steps to test your application of the PHP SDK.

  1. Upload the example file to a host folder and access the sample application using the URL.

    Example: http://localhost:8080/sampleweb.php

  2. View the page source. Review contents and SEO <metadata> tags should appear inside the BVRRContainer.
  3. Verify that SEO <metadata> tags, as shown in the following code sample, appear after every review.
<ul id="BVSEOSDK_meta" style="display:none  !important">
    <li data-bvseo="sdk">bvseo_sdk, p_sdk, bvseo-x.y.z.0</li>
    <li data-bvseo="sp_mt">getContent, method:CLOUD, 188ms</li>
    <li data-bvseo="ct_st">REVIEWS, PRODUCT</li>
</ul>

If the SEO <metadata> tags do not match as shown in the code sample, troubleshoot and take appropriate action based on the error message displayed in the SEO <metadata> tag.

PHP SDK inputs and features

This topic provides details about the core classes in the BVSEO SDK, including configuration options and methods of use for the PHP platform.

Configuration

Configuration settings are added as BV class constructor parameters. Set configuration properties by placing them in the options array with the attribute in lowercase as a key and value.

PHP usage

Set EXECUTION_TIMEOUT to 5000 by adding it to the options array key with value of execution_timeout => 5000.

$bv = new BV(array(
// Required fields
'cloud_key' => 'myshco-3e3001e88d9c32d19a17cafacb81bec7',
'bv_root_folder' => 'Main_Site-ja_JP',
'subject_id' =>’5000001’,
// Our optional parameters
'execution_timeout' => 5000,
));

Adding properties

Adding and setting attributes changes the functionality and behavior of the SDK. Configuration options are listed in the following PHP SDK configuration attributesPHP SDK parameters tables.

All configuration settings are added when you instantiate the BV class.

PHP SDK configuration attributes

Attribute Type Description
CLOUD_KEY Required Used to locate the cloud SEO files. Contact Bazaarvoice to obtain the value you need for this property. This attribute is optional if LOAD_LOCAL_FILES is used.
BV_ROOT_FOLDER Required The folder where SEO files are located. This is also known as the display code. Unique root folders are created for each deployment zone and locale.Contact Bazaarvoice to obtain the value you need for this property.
base_url Required URL that is used to create pagination links. Bazaarvoice will add the parameter bvstate to the base_url. In most cases, this should include the product or service page's canonical URL.

Required for product reviews. The URL can be absolute, relative, or blank (null is allowed).
page_url Required Sends all query parameters attached to the current URL. Bazaarvoice will use these parameters to determine which page of reviews or questions & answers content to include. It is not required to send the full URL.
subject_id Required Identifier for the SEO subject to retrieve the content, which depends on the content you want to receive. For Reviews and Questions, this is the ProductID.

SEO_SDK_ENABLED

Optional Boolean value used to turn SEO SDK ON (True) or OFF (False).

Default: True
EXECUTION_TIMEOUT Optional Time in milliseconds (ms) to complete the SEO call for user-agents and search engine bots (such as browsers) not in CRAWLER_AGENT_PATTERN.
Default: 500
EXECUTION_TIMEOUT_BOT Optional Time in milliseconds (ms) to complete the SEO call for search engine bots that match CRAWLER_AGENT_PATTERN.

Default: 2000.
CRAWLER_AGENT_PATTERN Optional Overrides the default list of search engine bot user agents. You can add and remove agents from the list. Multiple values are separated by “|”.
Default:msnbot|google|teoma|bingbot|yandexbot|yahoo.
STAGING Optional

Set to True to get SEO contents from staging or False to get SEO contents from production. Not applicable when using LOAD_SEO_FILES_LOCALLY.

Default: False

Note: Be cautious when setting the SDK to retrieve staging data (True). It is common to forget to disable staging data.
SOCKET_TIMEOUT Optional

Used internally by the SDK as a timeout for establishing connection and reading complete contents.

Do not modify this value unless there is a network or bandwidth issue causing frequent socket/read timeouts. This is used for cloud SEO only and is not applicable when using LOAD_SEO_FILES_LOCALLY.

Default: 2000 ms

CONNECT_TIMEOUT Optional Used internally by the SDK as a timeout for establishing connection to cloud SEO. Do not modify unless it is necessary.
Default: 2000 ms
CHARSET Optional Use this string input to when character sets other than UTF-8 are used. For example, when the Shift JIS character set is used, the input should be "shift_jis"

Default: Uses the default value set by your OS.
SSL_ENABLED Optional

Set this value to "true" if SSL connections are required. Not applicable when using LOAD_SEO_FILES_LOCALLY.

Default: False

PROXY_HOST Optional Proxy support is needed by some clients for security reasons. The most common use case is when firewall rules can only be set for an IP address, not a domain. Cloud SEO uses a wide range of IP addresses that are subject to change at any time, so Bazaarvoice does not provide cloud SEO IP addresses to clients. To enable proxy, PROXY_HOST and PROXY_PORT must be set. Not applicable when using LOAD_SEO_FILES_LOCALLY.
PROXY_PORT Optional Port number on which the proxy/gateway system is listening. To be used along with PROXY_HOST.
LOAD_SEO_FILES_LOCALLY Optional (Not recommended.) Local file configurations may be required to overcome system limitations. A local file system can be fragile since Bazaarvoice is not responsible for the daily retrieval, unpacking, and distribution of SEO files. To enable local files, LOCAL_SEO_FILE_ROOT must be set. Possible values are either True or False.
LOCAL_SEO_FILE_ROOT Optional

(Not recommended.) Attribute to set the root path of the extracted SEO contents to BV_ROOT_FOLDER on the local file system. Should be used along with LOAD_SEO_FILES_LOCALLY.

content_type Optional Set according to which method is called. Use with SEOGetContent.
subject_type Optional Set according to which method is called.

Content retrieval

After you create a BV class instance, it can call questions and reviews.

PHP usage

$BVContent = $bv->reviews->getContent();

BVUIContent APIs

API Purpose
getContent() Gets the complete content of the subject. Supported content types include REVIEWS and QUESTIONS. These are set inside BVParameters. Inject this content in the rating summary section of the product display page. The contents collected will be injected as a single block of markup. This includes the main content and aggregate content where applicable.
getReviews() Gets the reviews section and omits the aggregate section of the content type REVIEWS. This content should be injected to the Review section of the product display page.
getAggregateRating() Gets the aggregate rating section of the REVIEWS content type. Inject this content in the rating summary section of the product display page.

PHP code examples

The following code examples show the usage of BVSEO in PHP. Ensure that you update your code to use proper values.

Use this example code to return aggregate rating and review content. Bazaarvoice recommends this code for PDPs.

<?php
//Define the base and page URLs; ensure the protocol (http or https) matches the one used in the production site 
$base = 'http://' . $_SERVER['HTTP_HOST'];
$page = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];

//Provide cloud_key, bv_root_folder, and subject_id
require('bvseosdk.php');
$bv = new BV(array(
    'bv_root_folder' => 'Main_Site-en_US',
    'subject_id' => 'subjectID',
    'cloud_key' => 'company-384757834788734',
    //page_url MUST include any and all URL parameters that were present in the page request; otherwise only page 1 of content can be indexed
    'page_url' => $page,
    //base_url is the shortest possible URL that will direct to this particular product page
    'base_url' => $base   
    ));
?>
<!DOCTYPE html>
<html>
    <head>
        <title>BV SDK PHP Example - Simple Ratings & Reviews (recommended method)</title>
    </head>
    <body>
        <div itemscope itemtype="http://schema.org/Product">
        <meta itemprop="name" content="ProductName" />
        <div data-bv-show="rating_summary" data-bv-product-id="ExternalId">
            <?php echo $bv->reviews->getAggregateRating(); ?>
        </div>
        <div data-bv-show="reviews" data-bv-product-id="ExternalId">
            <?php echo $bv->reviews->getReviews(); ?>
        </div>
    </body>
</html>

Use this example code to return Questions & Answers content.

<?php
//Please provide cloud_key, bv_root_folder and subject_id
require('bvseosdk.php');
$bv = new BV(array(
    'bv_root_folder' => 'Main_Site-en_US',
    'subject_id' => 'subjectID',
    'cloud_key' => 'company-384757834788734',
    //page_url MUST include any and all URL parameters that were present in the page request; otherwise only page 1 of content can be indexed.
    'page_url' => 'http://www.company.com/category/sub-category?query=value',
    //base_url is the shortest possible URL that will direct to this particular product page
    'base_url' => 'http://www.company.com/category/sub-category',
    //Ensure the protocol, http:// or https://, matches the production site.
        ));
?><!DOCTYPE html>
<html>
    <head>
        <title>BV SDK PHP Example - Questions: GetContent</title>
    </head>
    <body>
        This is a test page for Questions: getContent<br>
        This will return Questions & Answers content<br><br>

        <div data-bv-show="questions" data-bv-product-id="ExternalId">
            <?php echo $bv->questions->getContent(); ?>
        </div>

    </body>
</html>

Use this example code to return Seller Ratings content.

<?php
//Please provide cloud_key and bv_root_folder
require('bvseosdk.php');
$bv = new BV(array(
   'bv_root_folder' => '',
   'cloud_key' => '',
   //page_url MUST include any and all URL parameters that were present in the page request; otherwise only page 1 of content can be indexed.
   'page_url' => '',
   'subject_id' => 'seller'
));
?><!DOCTYPE html>
<html>
<head>
   <title>BV SDK PHP Example - GetContent</title>
</head>
<body>
This is a test page for SellerRatings: getContent() <br>
GetContent() will return Seller Ratings content <br><br>

<div data-bv-show="reviews" data-bv-product-id="ExternalId">
   <?php echo $bv->sellerratings->getContent(); ?>
</div>
</body>
</html>

Use this example code to return Ratings & Reviews and aggregate content.

<?php
//Please provide cloud_key, bv_root_folder and subject_id
require('bvseosdk.php');
$bv = new BV(array(
    'bv_root_folder' => 'Main_Site-en_US',
    'subject_id' => 'subjectID',
    'cloud_key' => 'company-384757834788734',
    //page_url MUST include any and all URL parameters that were present in the page request; otherwise only page 1 of content can be indexed.
    'page_url' => 'http://www.company.com/category/sub-category?query=value',
    //base_url is the shortest possible URL that will direct to this particular product page
    'base_url' => 'http://www.company.com/category/sub-category',
    //Ensure the protocol, http:// or https://, matches the production site. 
        ));
?><!DOCTYPE html>
<html>
    <head>

    </head>
    <body>

        <div data-bv-show="reviews" data-bv-product-id="ExternalId">
            <?php echo $bv->reviews->getContent(); ?>
        </div>
    </body>
</html>

Best practices

The following best practices will help you maximize SEO benefit on your product review pages.

Note: The default settings for BVSEO support these practices.

Even if you have a reviews tab on a product overview page, users appreciate seeing review content when they scroll down the page. Without reviews on the overview page, search engines perceive your overview pages as stale. Adding eight reviews to the page substantially increases the freshness score in the Google algorithm. Additionally, pages with some visible reviews (not under a tab) more consistently receive rich snippet stars in Google search results.

Follow these steps to set the number of reviews to display on the product overview page:

  1. From Site Manager, locate the implementation you want to configure.
  2. Select Edit next to the implementation to open configuration.
  3. Under User Experience, select Display Options, and select the Ratings & Reviews tab.
  4. Scroll down to the Reviews on First Page text box. Enter the number of reviews you want the page to show.

If you don't have access to Configuration in the Bazaarvoice Portal, file a support ticket to set the number of reviews.

This element of the BVSEO strategy is most likely to help your existing pages rise in search results for target phrases.

Sorting by relevance is better for both SEO and conversion. The relevance algorithm looks for reviews that are rich with content and recently published, so it loads your initial display of reviews with content that attracts search engines. This element of the BVSEO strategy improves a page's content-to-link ratio, density of target keywords, and the volume of synonyms and adjectives that support target keywords.

Follow these steps to set the sorting methods available to users:

  1. From Site Manager, locate the implementation you want to configure.
  2. Select Edit next to the implementation to open configuration.
  3. Under User Experience, select Display Options, and select the Ratings & Reviews tab.
  4. Scroll down to Review Sorting. Under the Review Sort Options list, check the Most Relevant box to enable relevance sorting.

If you don’t have access to Configuration in the Bazaarvoice Portal, file a support ticket to set the sorting methods.

Extensive testing confirms that both users and search engine bots react most favorably when your site contains multiple pages for a product, and when pages after the overview contain about 30 reviews each. Whether you use the BVSEO SDKs or implement your own solution, ensure that no more than 30 reviews appear on each page.

If you considered pagination in the past and concluded that it was difficult to implement, be aware that the current BVSEO implementation method has simplified the process significantly. This element of the strategy is most likely to increase long-tail traffic.

The new pages that result from pagination are the optimal place to target keywords that contain the word "reviews." In most cases, adding "reviews" to a logical place in the title and heading tags will help the pages rank highly for competitive search phrases like "[your shoe brand] reviews" or "[your hotel name] reviews."

This element of the BVSEO strategy is most likely to help your pages rank highly for phrases that contain the word "reviews."

Google awards rich snippet stars to web pages that contain social review content with clean and proper schema.org markup, and that do not hide important details. Rich snippet stars are the stars that appear in Google search results, as shown in the following image.

The following notes and suggestions are based on the BVSEO team's experience with hundreds of clients since the launch of Google's rich snippet stars.

  • For rich snippet stars to display successfully, Google's search engine bots must not perceive that review summary content is hidden by CSS in any way. You might have to alter the way tabs are implemented, or implement reviews outside of a tab, if rich snippet stars don't show up in search results within 3-4 weeks of your implementation.

  • While the Google Structured Data Testing Tool is very helpful, it is much more generous than Google Web search.
  • When Google first launched rich snippet stars, the company maintained an allowlist and blocklist (sometimes called a "whitelist" and "blacklist") for awarding the stars. Remnants of the lists might still be active.

  • The decision of whether or not to display rich snippet stars is up to Google. Once the schema.org code is in place, wait a few weeks. If the steps in the "Structured markup and rich snippet stars" section of the FAQs do not work, review Google's rich snippet troubleshooting guidelines at Rich snippets not appearing .
  • BVSEO code is consistent across our clients, and is operating smoothly on their millions of web pages. If there is a problem, confirm that BVSEO is properly configured for schema.org type, then focus on the environment around the BVSEO code.

The BVSEO SDKs support both cloud SEO and local file method (previously "smart SEO") configurations. Cloud SEO is strongly recommended over the local file system configuration for the following reasons:

  • Cloud SEO files are more up to date.
  • Cloud SEO is more reliable and stable.
  • Bazaarvoice is responsible for cloud SEO file publishing processes, which reduce internal maintenance responsibility for the client.
  • Cloud SEO is often faster at retrieving content than the local network and file system.

If technical limitations make the cloud-based solution not feasible for your site, Bazaarvoice also offers a downloadable daily zip file that contains everything you need to make your implementation SEO-friendly.

If you need to use the local file method, complete the following steps and refer to the local code examples for your platform to complete a local SEO integration.

Note: This procedure uses the ZIP format of compression, which is standard for Windows. Alternatively, you can receive files in the GZIP format, which is standard for UNIX systems. If you want to use GZIP, go to the SEO page in configuration and select the GZIP option for Compression type. If you don’t have access to Configuration in the Bazaarvoice Portal, file a support ticket to use the GZIP format.
  1. Set up a daily process to download and decompress a ZIP file that contains the search-friendly content for your product pages.
  2. Ensure that the unzipped files are available via your web server's file system.
  3. Implement the SEO integration SDK with the Internal File Path variable set to the location of the unzipped files. Refer to Implementing BVSEO for instructions on downloading and implementing the SDK in the server-side programming language you use.
Note: It is important that you update the ZIP file daily. Downloading and updating less frequently reduces the freshness of your website content to search engines, and therefore reduces the value of the SEO implementation.

FAQs

Use the information in the following sections to troubleshoot your BVSEO implementation.

Bazaarvoice recommends you use the Safari web browser, available for Windows and Mac, for web-based testing.

I use a specific eCommerce platform. Does Bazaarvoice offer plug-ins?

Yes. Bazaarvoice offers Demandware, Magento, Hybris, and GSI plug-ins to deploy BVSEO. Contact your Bazaarvoice sales or technical services representative for more information.

My website is built using a different technology, such as Ruby or Perl. Can I use the BVSEO SDKs?

If your website is built using a different technology, you will need to develop a custom solution. The BVSEO SDKs are open sourced, published in GitHub, and provide a reliable guide for developing a custom solution.

How do I use BVSEO with an API?

BVSEO does not support APIs. For API documentation, refer to developer.bazaarvoice.com.

You can use caching to improve speed and efficiency in ways that affect BVSEO integration.

I use a page-level cache. How do I ensure that SEO-friendly content is always included in the cached version of my page?

If implementing BVSEO on pages using a page-level cache, increase EXECUTION_TIMEOUT to 2000ms.

Does the page use the complete URL as its cache key?

BVSEO uses bvrrp, bvqap, bvsyp, and bvpage as URL parameters to manage pagination. The following URLs must be treated as unique pages by page-level caching systems:

  • http://example.com
  • http://example.com?bvrrp=1360/reviews/product/5/10246.htm

If you are not following this method, the cache system and URL masking system must be updated as part of your BVSEO deployment.

I use a local cache. How do I ensure that SEO-friendly content is always included?

It is very common to use a local caching system to reduce the number of calls that the system makes to the cloud SEO servers. The SDK does not include caching services, but the response from the SDK can be cached. TTL (time-to-live) for the local cache should not exceed three hours.

Does the page contain canonical tags?

Canonical tags appear in the page's source code as <link rel="canonical" href=. On pages where BVSEO is implemented, canonical tags must be updated or removed when the product contains more than one page of reviews. (One page contains eight reviews.) BVSEO paginates the product page so all reviews are in the search engines’ indexes. Canonical tags that point away from a pagination URL will cause search engines to ignore the paginated content.

Note: Refer to Best practices for more information on pagination.

BVSEO appends pagination parameters to your URL in the form of name/value pairs. When any of the BVSEO pagination parameters (bvstate, bvrrp, bvqap, bvsyp, bvpage) are present, perform one of the following actions:

  • Remove the canonical tag. This is the most common, recommended solution.
  • Update the code that generates the canonical tag for your page to append the name/value pair. Use the appropriate pagination parameter as it appears in your URL for the name and an appropriate value depending on the parameter. For example, if your page uses the bvstate parameter, you might append bvstate=pg:2/ct:r/st:p to the canonical tag in your page.

If rel="canonical" is present in the page, does the canonical URL match the URL of the page being evaluated?

It's not uncommon for canonical tags to point to an alternate URL. If the canonical URL points away from the page being evaluated, get the source code from the canonical page and use that instead.

Can you add rel="next" and rel="prev" links to my pagination links?

Adding rel="next" and rel="prev" to links is not a recommended practice. Bazaarvoice's testing and interpretation of Google’s pagination guidelines proves that these tags should not apply to a list of reviews. The tags tell searches to default to the first page of reviews only, even if more relevant content exists on a subsequent page. For more details about this recommendation, read Google's paginated content guidelines .

Bazaarvoice recommends using the cloud-based file method. It requires less effort and is more reliable than the local file method, which requires more effort and long-term management. Refer to the "Select a file method" section of best practices for more information.

Note: The questions and solutions in this section apply to the cloud-based file method.

Is a local cache used to reduce server-side calls to the cloud?

BVSEO makes an HTTP or HTTPS request to seo.bazaarvoice.com (seo-stg.bazaarvoice.com for staging), which returns formatted HTML as a string. While the cloud service contains caches for exceptionally efficient delivery (often less than 20ms), some clients opt to add an additional layer of local caching. If a local cache is used, Bazaarvoice recommends a maximum TTL of one hour.

Is a proxy used?

If the firewall requires an IP address, you must set up a proxy to provide a consistent IP address. BVSEO must have access to seo.bazaarvoice.com (seo-stg.bazaarvoice.com for staging) via HTTP or HTTPS. BVSEO uses floating IP addresses in the cloud, which cannot guarantee consistent IP addresses. To set up a proxy, use BVClientConfig.PROXY_HOST and PROXY_PORT to point the SDK to the proxy.

Should firewall settings be adjusted?

BVSEO must have access to seo.bazaarvoice.com (seo-stg.bazaarvoice.com for staging) using HTTP or HTTPS. If the firewall restricts access to this address, adjustments are needed.

Are SSL connections required?

While the content retrieved from seo.bazaarvoice.com does not contain any data that needs to be protected, security policies may require that all server-side connections are protected by SSL. SSL support is available in the Java SDK v2.1 (and above) and .NET SDK v2.1 (and above). To enable SSL connections, set BVClientConfig.SSL_ENABLED to true when deploying the SDK.

How do execution timeouts work?

The SDK configuration includes two execution timeout settings: EXECUTION_TIMEOUT and EXECUTION_TIMEOUT_BOT.

  • EXECUTION_TIMEOUT—Defines the maximum amount of time allowed for the completion of the BVSEO injection for normal end users.
  • EXECUTION_TIMEOUT_BOT—Defines the maximum amount of time allowed for user agents defined in the CRAWLER_AGENT_PATTERN field.
Note: If the BVSEO injection exceeds the allowed timeout, the system will revert to a JavaScript-only injection.

Does the SDK include bot detection?

Older versions of the BVSEO SDK included a bot detection feature that completely blocked the injection if a user agent was detected. The BOT_DETECTION configuration was removed from the BVSEO SDK beginning with version 2.1. If you want to replicate the bot detection functionality, set EXECUTION_TIMEOUT equal to 0.

Bazaarvoice supports and recommends schema.org Microdata for structured markup, as it yields the best results of all formats we have tested. Bazaarvoice uses the schema.org/Product page to guide our tagging.

Answer the following important questions to ensure that your schema.org markup is set up correctly.

Are you using the latest version of Ratings & Reviews?

Ensure that you are using the latest version of Ratings & Reviews to deploy important updates. Check your Configuration settings for updates.

Does the page contain schema.org markup?

If the page where BVSEO is being deployed contains any schema.org markup, you must pay meticulous attention to detail to ensure that the schema markup does not conflict. All schema.org markup must be properly nested in a single hierarchy. Carefully audit the HTML output to ensure a proper schema.org code hierarchy is present.

Rich snippet stars are the stars that appear in Google search results, as shown in the following image.

Read this blog post for information about successfully displaying rich snippet stars.

Refer to the following questions to ensure that Google's rich snippet stars appear in search results for your product pages.

Is the page using schema.org Microdata?

For best results, pages should use schema.org Microdata. For more information, refer to Getting started with schema.org using Microdata .

If there is a schema.org/WebPage declaration, are all other schema.org elements nested within it?

While the schema.org/WebPage declaration is not required, many web sites use it. It's required that WebPage be the outermost schema.org-related node.

Is there a schema.org type relevant for the content?

For rich snippet stars to display, include a schema.org type on the page. The schema.org/Product type works well for most eCommerce websites. However, other types such as LocalBusiness, Recipe, Event, or Restaurant hierarchies might be more accurate for your page.

Note: schema.org/Product is excluded by default in BVSEO markup because it must open before the Bazaarvoice module and close after it. Before February 2015, Bazaarvoice enabled this feature by default. However, it is no longer recommended for schema.org/Product to reside within the Bazaarvoice containers.

Is the product name listed within the schema.org/Product class?

The product name should be within the schema.org/Product class using <div itemprop=name>[ProductName]</div> or <meta itemprop="name" content="[ProductName]" />.

Is a schema.org/Organization type present in the page?

While it seems logical that Google would display rich snippet stars for organizations, it did not when Bazaarvoice last tested it. Bazaarvoice recommends schema.org/LocalBusiness for organizations with a physical location.

Is there only one schema.org type?

Google will display rich snippet stars only for sites that contain a maximum of one type.

Is schema.org/AggregateRating correctly nested within schema.org/Product (or the type that best fits your content)?

AggregateRating, and all sub-elements, must be nested within schema.org/Product.

Is schema.org/AggregateRating present and NOT hidden by CSS or NOSCRIPT?

BVSEO hides portions of the HTML to reduce flashing while AJAX content decoration occurs. However, aggregate rating markup and pagination links must not be hidden by CSS or a NOSCRIPT tag. For example, wrapping the BVSEO content with <div style="display:none;"> prevents Google from rendering rich snippet stars.

Does itemprop="name", as declared in the type, match the content of itemprop="itemReviewed" supplied by BVSEO?

BVSEO code may look repetitious because itemprop="itemReviewed" is repeated many times. However, rich snippet stars display more consistently when both AggregateRating and Review schemas contain this tag, which confirms that the page is still addressing the same item. This is especially true for pages with extensive markup.

Are there any structured markup conflicts?

Use only one type of structured markup. Pages should not contain data-vocabulary.org or hreview (microformats) content. All structured markup should use schema.org format.

Does outbound or inbound syndication of my content run the risk of being duplicated?

Bazaarvoice syndicates content across hundreds of brands and retailers and is not concerned about duplicate content causing issues. When content is duplicated or syndicated between a brand and a retailer (in either direction), it is beneficial for several reasons:

  • Good user experience—Since products are sold and displayed on both retailer and brand sites, shoppers want to discover feedback from people who have used the products, and they expect feedback to appear wherever they are online. If there were no reviews or a diminished number of reviews, it would contribute to a poor user experience.
  • No Google issues—Duplicate content is defined by Google as "substantive blocks of content within or across domains that either completely match other content or are appreciably similar." Since reviews are only a subset of the product page, and they are mixed in between the retailer’s and the brand’s reviews, we do not anticipate issue with duplicate content. Bazaarvoice has never received notice from clients that they received a duplicate content penalty or warning in Google Webmaster Tools, the system Google uses to tell webmasters if they do something wrong.
  • Syndication delay—Bazaarvoice developed a feature into our platform called “syndication delay." Any content that is marked to be syndicated to another site has to wait for seven (7) days before it is syndicated. That way, Google has time to index the content on the original site, and then when it finds the same review on another site, it knows that the content has been shared. Since all of this adds so much value to users, there is no issue with Google. Syndication delay is configurable via a support request through the Support Community .

Bazaarvoice recommends that every website on our platform includes variety of content sources. There are a number of ways to do this, and our client services teams can help craft a robust content strategy for your website. Syndicated content should be a portion, not the entirety, of any content generation strategy.

I want to find out if Google is indexing my user-generated content. Where do I start?

  • Find a product page that has more than one page of review content.
  • View the source code of page 1, which is the default load of the product page.
  • In a separate browser window, view the source code of the search-friendly version of page 2.
  • It is easiest to review the source code in a text editor after you have processed it through Tabifier . To use Tabifier, copy the source code, paste it into the Code in text box, and select Tabify. Then, copy the code from the Code out text box into your preferred text editor (BBEdit, TextPad, or similar) for analysis. Do this for both page 1 and page 2.

Is Google indexing my user-generated content (UGC)?

Bazaarvoice has developed metadata that describes UGC on your website so you can assess if Google is indexing this content. You can choose the appropriate command from the options in the following list and perform a Google search of the bolded text using your domain in place of client.com. These searches will return a list of URLs where reviews are indexed and the total number of indexed pages.

Note: If you are using the Bazaarvoice API, these commands will not return any results since metadata is not included in the API. The Google search engine has the most advanced website indexing capability. Google has the largest search engine market share worldwide and goes to the greatest lengths to decipher advanced website coding techniques in an effort to know exactly what a user sees when visiting a page. Other search engines such as Bing, Baidu, and Yandex typically follow Google's indexing capabilities within 1-2 years.

The following searches will help you determine what Google is indexing.

  • site:client.com intext:bvseo_fps—This search returns pages implemented using Bazaarvoice's most current client-side (JavaScript or "hosted display") solution. If you've implemented our platform (or upgraded) since November 2013, use this search option.

  • site:client.com intext:bvseo_bulk—This search returns pages implemented using Bazaarvoice's most current server-side solution. If you've implemented our platform (or upgraded) since November 2013 and completed the "Smart SEO" or "Cloud SEO" implementation step,use this search option.
  • site:client.com intext:bvseo_pps—This search returns pages implemented using Bazaarvoice's legacy client-side (JavaScript or hosted display) solution. If you've implemented our platform on your site before November 2013 and haven't made many changes since, use this search option.
  • site:client.com intext:bvseo_lps—This search returns pages implemented using Bazaarvoice's legacy server-side solution. Historically, server-side content is the only type of content that search engines could read. If you've implemented our platform on your site before November 2013, and haven't made many changes since, use this search option.

What add-ons can I use to filter search results?

You can append the following add-ons to the above commands to filter your search results.

  • intext:co_hasreviews—Append this command to return only pages that have reviews.

  • intext:co_noreviews—Append this command to return only pages that do not have reviews.
  • intext:bvpage2n—Append this command to return pages of review content beyond the first 8 reviews. For example, consider a product that displays 8 reviews on the first page, 30 reviews on the second page, and 12 reviews on the third page for a total of 50 reviews. This query will return two URLs for bvpage2n.

  • intext:bvpage1—Append this command to return only the first page of review content.

Troubleshooting

Refer to the following sections to help troubleshoot your BVSEO implementation.

Note: Bazaarvoice recommends using the Safari web browser for web-based testing. Safari is available for both Windows and Mac.

Perform the following diagnostic searches in Google.

Note: These searches will only work if BVSEO is in a live environment where Google can find the code and content. If BVSEO is not accessible to Google, skip diagnostic queries and proceed to Manual Verification.

Edit the URLs in these searches to replace example.com with the domain you are testing. Then, load the URL from a web browser.

Does this diagnostic query provide results on BVSEO for unpaginated URLs?

http://www.google.com/search?num=100&filter=0&q=intext:bvseo_bulk+-inurl:bvrrp+site:example.com

Note: This only checks page 1.

Does this diagnostic query provide results about BVSEO for paginated URLs on pages 2 and above?

http://www.google.com/search?num=100&filter=0&q=intext:bvseo_bulk+inurl:bvrrp+site:example.com

If the answer to both questions is yes, load one of the pages listed in the search results and continue to Additional verification. If not, proceed to Manual Verification.

Does page 2 contain a canonical tag that points to a different URL?

This is one of the most common mistakes. If the page contains a rel="canonical" tag, the URL must contain the bv pagination parameter. In most cases, clients wrap the canonical tag with a conditional and do not include it when any of the following parameters appear on the URL: bvrrp, bvqap, bvsyp, bvstate, and bvpage. Refer to Canonical tags for more information.

Is the word reviews emphasized in the heading of pages 2–n?

To improve rank for search phrases that contain the word reviews, we strongly recommend appending the word reviews to the <title> and <h1> tags when bvrrp appears in the URL.

Once Tabified, how many total lines of code were present in the page 1 code that was audited?

Across all Bazaarvoice clients who have properly deployed BVSEO, clients with clean and minimalistic HTML are given rich snippet stars much more consistently. Bazaarvoice has noted that pages with approximately 600 total lines of code tend to get rich snippet stars in 100% of diagnostic searches while pages with over 4,000 lines of code on each page tend to get stars about 60% of the time.

View the HTML source code to investigate the following questions.

Is BVSEO code found in the HTML source code?

Search for BVSEOCPS_GEN in the source code (use Ctrl+f or Command+f to run the Find query). If it is not found, search for BVRRSourceID. If neither of these are found, BVSEO is not in your page. Contact your developer to review the Bazaarvoice integration.

Do pagination links work properly?

If pagination links are intentionally disabled in the BVSEO configuration, proceed to Additional verification.

Note: Search-friendly pagination is recommended a majority of the time.
  1. Find a product that has more than one page of reviews. While viewing the source code, search for begin-pagination. Shortly after that, there should be an HTML link that begins with <a href=, and contains either bvrrp or bvpage.
  2. Note: If {INSERT_PAGE_URI} appears, pagination links are not working properly. You need to redeploy BVSEO using an SDK.

    If you are using the Ratings & Reviews configuration, the following code should appear:

    <div itemscope itemtype="http://schema.org/Product">
        <div data-bv-show="reviews" data-bv-product-id="ExternalId">
        <!--begin-bvseo-reviews-->
            <meta itemprop="name" content="Product Name" />   
            <!--begin-aggregate-rating--> 
            <div id="bvseo-aggregateRatingSection" itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating">
                <span class="bvseo-itemReviewed" itemprop="itemReviewed">Product Name</span> is rated
                <span class="bvseo-ratingValue" itemprop="ratingValue">4.8571</span> out of 
                <span class="bvseo-bestRating" itemprop="bestRating">5</span> by 
                <span class="bvseo-reviewCount" itemprop="reviewCount">14</span>.
            </div>
            <!--end-aggregate-rating-->
            <!--begin-reviews-->
            <div id="bvseo-reviewsSection">
                <!--content removed for example-->
            </div>
            <!--end-reviews-->
        </div>
    </div>
    
  3. If pagination links are working properly, select the link to page 2 in the Safari source code viewer and view the following code.
    <a href="http://www.softsurroundings.com/5/23986/P/Newport_Beach_Pant/View_All/?bvrrp=4398/reviews/product/2/23986.htm">

    Note that the page number appears immediately after /product/. Take note of the page you're attempting to load. The full URL will also appear in the address bar after the page loads.

  4. After the page loads, verify that the User Agent is still googlebot, or re-do the User Agent switcher to reload the page.
  5. Check if the appropriate page of SEO content has loaded into the source code. View the page's HTML source and find bvseo-bulk-cp in the source code. The number following cp- is the page number, as shown in the code below. This number should match the page number in the address bar.
        <ul id="BVSEO_meta" style="display:none;important">
        <li data-bvseo="bvDateModified">y_2020, m_11, d_30, h_16</li>
        <li data-bvseo="ps">bvseo_bulk, prod_bvrr, vn_bulk_3.0.12</li>
        <li data-bvseo="cp">cp_10, bvpage2n</li>
        <li data-bvseo="co">co_hasreviews, tv_34, tr_250</li>
        <li data-bvseo="cf">loc_en_US, sid_12345, prod, sort_[SortEntry(order=SUBMISSION_TIME, direction=DESCENDING)]</li>
        <li data-bvseo="diagnostics">clientName_YourClientNameHere</li>
    </ul>
    

    If you don't use the Ratings & Reviews configuration, find BVRRSelectedPageNumber in the HTML source code. The number after the tag will indicate the page number.

    If you confirm that the appropriate page of content loaded, pagination links work properly. Return to a product page, not the paginated version, and proceed to Additional verification.

BVSEO content is not found. Why?

An exceptionally low execution timeout may have occurred. To override this, you can enable developer tools and override the User Agent in Safari, as follows:

  1. To use Safari's built-in User Agent switcher, select the Show Develop menu in menu bar option from Preferences > Advanced. A menu labeled "Develop" is then displayed in the menu bar.
  2. Select the Develop menu and select User Agent > Other. A window is displayed that contains the current user agent.
  3. Add the word "googlebot" to the end, as shown below, and select OK.

The user agent will now cause the BVSEO SDK to operate using a more generous execution timeout while you are working inside that browser window or tab. You must go through this process again if you open a new browser window or tab.

If results were found for Diagnostic queries or Manual verification, open one of the pages found in search results and view the HTML source to investigate the following questions.

Are the contents refreshing as intended?

Find bvDateModified in the HTML source code. Date stamps are formatted YYYY-MM-DDThh:mmTZD, according to ISO 8601 standard . The date stamp adjacent to bvDateModified should always be less than two days old. For example:

<li id="bvDateModified">2014-06-15</li>

Is your page displaying production content?

Search for data-bvseo="cf” in the source code and look at the characters that immediately follow it. If you find prod, BVSEO is configured to use production data, which is what you want. If you find stg, BVSEO is configured to use staging data and you should contact your developer to fix it.

To verify that you're displaying the correct content, find itemprop="description” in the source code and find an instance where review content immediately follows, as shown in the example below:

<span itemprop="description">I got to try this chicken jerky flavor...

Compare the first few words of that review with the reviews displayed in the page for end users. If a new review has come into the system since the last SEO update, there may be a difference. Run this test a few times to verify.

Are the contents in the proper DIV?

View the source code and rendered HTML using the "view page source" feature of your browser. Verify that the BVSEO contents are located in the proper <div> tag. To determine this, look for rating summary or reviews in the source code. If the <div> tag opens and closes immediately as in this example:

<div data-bv-show="rating_summary" data-bv-product-id="ExternalId"></div>

The content is not in the proper format. The following code example shows what the <div> content should look like.

<div data-bv-show="reviews" data-bv-product-id="ExternalId">
    <!--begin-bvseo-reviews-->
        <!--begin-aggregate-rating--> 
        <div id="bvseo-aggregateRatingSection" itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating">
            <span class="bvseo-itemReviewed" itemprop="itemReviewed">Product Name</span> is rated
            <span class="bvseo-ratingValue" itemprop="ratingValue">4.8571</span> out of 
            <span class="bvseo-bestRating" itemprop="bestRating">5</span> by 
            <span class="bvseo-reviewCount" itemprop="reviewCount">14</span>.
        </div>
        <!--end-aggregate-rating-->

        <!--begin-reviews-->
        <div id="bvseo-reviewsSection">
            <!--content removed for example-->
        </div>
        <!--end-reviews-->
</div>

Is schema.org format used for structured markup?

Search for schema.org/AggregateRating in the source code. If that is not found, search for schema.org/Review. If neither is found, it is likely that the client is configured to use an old version of BVSEO and the configuration should be updated to use schema.org format for structured markup.

When BVSEO content is injected into the page? Are characters escaped?

BVSEO markup must appear as HTML, not escaped characters. Find begin-bvseo in the source code. If the content appears with escaped characters, as shown in the example below, contact your developer to solve the issue.

&lt;!--begin-bvseo-reviews--&gt;

The markup should look like this:

<!--begin-bvseo-reviews-->

Are search-friendly pagination links hidden by CSS or NOSCRIPT?

BVSEO uses a tested technique to decorate pagination links, but never hides them with CSS or NOSCRIPT. Google will not crawl links that are hidden by CSS or NOSCRIPT. It is a common mistake to add a style="display:none;" property to the <div> tag, which contains BVSEO. Doing so blocks search-friendly pagination.

Step 1: Add bvreveal=debug

  1. Add the bvreveal=debug parameter to the URL of any page where BVSEO is implemented.

    Example: http://yoursite.net/ExampleGetContent.aspx?bvreveal=debug

    The bvreveal=debug parameter adds BVSEOSDK_meta and BVSEOSDK_DEBUG lists to the source code, which contain information about your implementation. If there is no user-generated content (UGC), bvseo-msg will provide more details.

    Note: If pageURL is not set up correctly, bvreveal=debug will not work. If you do not provide a debug footer, pagination links may be incorrect.
  2. View the page's source code to find information about your implementation. This information is included in BVSEOSDK_meta and BVSEOSDK_DEBUG. Refer to the full example code at the end of this section.

Step 2: Check for content

Check if content exists for the requested contentURL, as described in the following steps:

  1. Find the contentURL in the BVSEOSDK_DEBUG list. Example: <li data-bvseo="contentURL">http://seo-stg.bazaarvoice.com/myshco-69cb945801532dcfb57ad2b0d2471b68/Main_Site-en_US/reviews/product/1/5000001.htm</li>
  2. From the terminal, run the curl –i command. Example: curl –i "http://seo-stg.bazaarvoice.com/myshco-69cb945801532dcfb57ad2b0d2471b68/Main_Site-en_US/reviews/product/1/5000001.htm"

If the curl command does not return content, it could be a firewall issue or no content exists for this ProductID. Contact your Bazaarvoice representative for further troubleshooting.

Error messages

The following error messages may appear when debugging.

  • HTTP status code of 0 was returned (or) connection refused to seo-stg.bazaarvoice.com—Indicates that a firewall exists on your network. Outbound requests from your network may be blocked by your firewall. Contact your IT team to sort out firewall issues.
  • The resource to the URL or file is currently unavailable—Indicates that something is wrong with the implementation configuration or no content was generated for the specified product.

Integration for new clients

  1. Install the Java, .NET, or PHP SDK.
  2. Define the cloud key, which is provided by Bazaarvoice.
  3. Define the root folder, which is provided by Bazaarvoice.
  4. Define the page URL by specifying the base_URL plus query strings and appended parameters. This is required regardless of whether your site uses query parameters. Bazaarvoice appends parameters for SEO pagination, and it is required that the page_URL capture these. Do not cache this on your side because the page_URL must update in real time.
  5. Define the base URL by specifying the canonical URL of the product page.
  6. Add the schema.org markup on the product page.
  7. If behind a firewall, contact your network or server operations team to add seo.bazaarvoice.com and seo-stg.bazaarvoice.com to the allowlist (sometimes called a "whitelist").
  8. Set STAGING to TRUE when implementing in a non-production (staging) environment.

Examples:

<%@page import="com.bazaarvoice.seo.sdk.model.ContentType"%>
<%@page import="com.bazaarvoice.seo.sdk.model.SubjectType"%>
<%@page import="com.bazaarvoice.seo.sdk.model.BVParameters"%>
<%@page import="com.bazaarvoice.seo.sdk.BVManagedUIContent"%>
<%@page import="com.bazaarvoice.seo.sdk.BVUIContent"%>
<%@page import="com.bazaarvoice.seo.sdk.config.BVClientConfig"%>
<%@page import="com.bazaarvoice.seo.sdk.config.BVSdkConfiguration"%>
<%@page import="com.bazaarvoice.seo.sdk.config.BVConfiguration"%>
<%@page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%><%

//Establish a new BVConfiguration. Properties within this configuration are typically set in bvconfig.properties.  
//addProperty can be used to override configurations set in bvconfig.properties.
BVConfiguration _bvConfig = new BVSdkConfiguration();
    _bvConfig.addProperty(BVClientConfig.CLOUD_KEY, "client-1234cloudkeygoeshere4321zxyz9876");
    _bvConfig.addProperty(BVClientConfig.BV_ROOT_FOLDER, "Main_Site-en_US"); //adjust this for each locale
    _bvConfig.addProperty(BVClientConfig.STAGING, "true");
//Prepare pageURL and SubjectID/ProductID values.       
String pageURL = request.getQueryString() == null ? request.getRequestURI() : request.getRequestURI() + "?" + request.getQueryString();
String subjectID = "ExternalId";        

//Set BV Parameters that are specific to the page and content type.
BVParameters _bvParam = new BVParameters();
    _bvParam.setBaseURI(request.getRequestURI()); // this value is used to build pagination links
    _bvParam.setPageURI(pageURL); //this value is used to extract the page number from bv URL parameters
    _bvParam.setContentType(ContentType.REVIEWS);
    _bvParam.setSubjectType(SubjectType.PRODUCT);
    _bvParam.setSubjectId(subjectID);
BVUIContent _bvOutput = new BVManagedUIContent(_bvConfig);

//Get content and place into strings, which output into the injection divs.
String sBvOutputSummary = _bvOutput.getAggregateRating(_bvParam);  //getAggregateRating delivers the AggregateRating section only
String sBvOutputReviews = _bvOutput.getReviews(_bvParam);  //getReviews delivers the review content with pagination only%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<body>
<h1>Ratings & Reviews integration of BVSEO</h1>
<h2>Using cloud for file retrieval</h2>

<div itemscope itemtype="http://schema.org/Product">
  <meta itemprop="name" content="The Amazing Wonder Ball" />
  <div data-bv-show="rating_summary" data-bv-product-id="ExternalId">
    <%=sBvOutputSummary%>
  </div>

  <div data-bv-show="reviews" data-bv-product-id="ExternalId">
    <%=sBvOutputReviews%>
  </div>
</div>

</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using BVSeoSdkDotNet.Config;
using BVSeoSdkDotNet.Content;
using BVSeoSdkDotNet.Model;

namespace SampleWebApplication
{
   public partial class Sample : System.Web.UI.Page
   {
      protected void Page_Load(object sender, EventArgs e)
      {

         BVConfiguration bvConfig = new BVSdkConfiguration();

         String cloudKey = Request.QueryString["cloudkey"];
         String staging = Request.QueryString["staging"];
         String testing = Request.QueryString["testing"];
         String rootFolder = Request.QueryString["site"];
         String productIdParam = Request.QueryString["productid"];

         String subjectId = "5000001";

         if (cloudKey != null)
         bvConfig.addProperty(BVClientConfig.CLOUD_KEY, cloudKey);
         else
         bvConfig.addProperty(BVClientConfig.CLOUD_KEY, "myshco-3e3001e88d9c32d19a17cafacb81bec7");
         if (staging != null)
         bvConfig.addProperty(BVClientConfig.STAGING, staging);
         else
         bvConfig.addProperty(BVClientConfig.STAGING, "true");
         if (testing != null)
         bvConfig.addProperty(BVClientConfig.TESTING, testing);
         else
         bvConfig.addProperty(BVClientConfig.TESTING, "false");

         if (rootFolder != null)
         bvConfig.addProperty(BVClientConfig.BV_ROOT_FOLDER, rootFolder);
         else
         bvConfig.addProperty(BVClientConfig.BV_ROOT_FOLDER, "9344");

         if (productIdParam != null)
         {
            //if productIdParameter is null then use the default value.  If it's not null then use the parameter.  If category
            subjectId = productIdParam;
         }
         else
         subjectId = "5000001";

         bvConfig.addProperty(BVClientConfig.SEO_SDK_ENABLED, "true");  // use this as a kill switch
         bvConfig.addProperty(BVClientConfig.LOAD_SEO_FILES_LOCALLY, "false"); // set to false if using cloud-based content
         bvConfig.addProperty(BVClientConfig.LOCAL_SEO_FILE_ROOT, "/");

         bvConfig.addProperty(BVClientConfig.CRAWLER_AGENT_PATTERN, "yandex");

         bvConfig.addProperty(BVClientConfig.EXECUTION_TIMEOUT, "1500");
         bvConfig.addProperty(BVClientConfig.EXECUTION_TIMEOUT_BOT, "2000");

         var bvParameters = new BVParameters
         {
            BaseURI =
            Request.Url.ToString().Contains("?")
            ? Request.Url.ToString().Substring(0, Request.Url.ToString().IndexOf("?"))
            : Request.Url.ToString(),
            PageURI = Request.Url.ToString(),
            ContentType = new BVContentType(BVContentType.REVIEWS),
            SubjectType = new BVSubjectType(BVSubjectType.PRODUCT),
            SubjectId = subjectId
         };

         BVUIContent bvOutput = new BVManagedUIContent(bvConfig);
         SEO_BVRRSummaryContainer.InnerHtml = bvOutput.getAggregateRating(bvParameters);
         SEO_BVRRContainer.InnerHtml = bvOutput.getReviews(bvParameters);
      }
   }
}
<?php
   //Define the base and page URLs; ensure the protocol (http or https) matches the one used in the production site 
   $base = 'http://' . $_SERVER['HTTP_HOST'];
   $page = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];

   // Include the bvseosdk.php
   require('bvseosdk.php');

   // Pass an array with configuration properties and parameters
   $bv = new BV(array(
      //update the following line to use actual values, which can be obtained from Bazaarvoice
      'cloud_key' => ‘myshco-3e3001e88d9c32d19a17cafacb81bec7’, 
      'bv_root_folder' => 'Main_Site-ja_JP',

      'page_url' => $page,

      //base_url is the shortest possible URL that will direct to this particular product page
      'base_url' => $base,   

      'staging' => TRUE,

      //because the subject is Product, set the productId below
      'subject_id' =>’5000001’,

      'execution_timeout' => 1500,
      'execution_timeout_bot' => 2000,
      'seo_sdk_enabled' => TRUE
      ));
?>
<!DOCTYPE html>
<html>
   <head>
      <title>BV SDK PHP Example - GetContent</title>
   </head>
   <body>
      This is a test page for Reviews: getContent() <br>
      GetContent() will return reviews and aggregate content <br><br>

      <div data-bv-show="reviews" data-bv-product-id="ExternalId">
         <?php echo $bv->reviews->getContent(); ?>
      </div>
   </body>
</html>

Integration for existing clients

You must update your BVSEO integrations when you add the BV loader to your site.

Java and PHP

Make the following changes to your Java and PHP BVSEO integrations:

  • Replace <div id="BVRRSummaryContainer"> with <div data-bv-show="rating_summary" data-bv-product-id="ExternalId">
  • Replace <div id="BVRRContainer"> with <div data-bv-show="reviews" data-bv-product-id="ExternalId">
  • Replace <div id="BVQAContainer"> with <div data-bv-show="questions" data-bv-product-id="ExternalId">

where:

  • data-bv-show—Instructs the BV loader to display the specified feature.
  • data-bv-product-id—Instructs the BV loader to display the feature for a specified product ID. The product ID must match the ExternalId provided in the product catalog.

.NET

Make the following changes to your .NET BVSEO integrations:

  • Replace <div id="BVRRSummaryContainer" runat="server"> with <div id="SEO_BVRRSummaryContainer" runat="server" data-bv-show="rating_summary" data-bv-product-id="ExternalId">
  • Replace <div id="BVRRContainer" runat="server"> with <div id="SEO_BVRRContainer" runat="server" data-bv-show="reviews" data-bv-product-id="ExternalId">
  • Replace <div id="BVQAContainer" runat="server"> with <div id="SEO_BVQAContainer" runat="server" data-bv-show="questions" data-bv-product-id="ExternalId">

where:

  • data-bv-show—Instructs the BV loader to display the specified feature.
  • data-bv-product-id—Instructs the BV loader to display the feature for a specified product ID. The product ID must match the ExternalId provided in the product catalog.

Update the code referencing those element IDs as well:

  • Replace BVRRContainer.InnerHtml with SEO_BVRRContainer.InnerHtml
  • Replace BVRRSummaryContainer.InnerHtml with SEO_BVRRSummaryContainer.InnerHtm
  • Replace BVQAContainer.InnerHtml with SEO_BVQAContainer.InnerHtml

Be aware that changes made to BVSEO in the staging environment are updated once a week only, on Saturday.

Verify the following: