The Embedded Viewer API lets you embed book content from
[Google Books](https://books.google.com/) directly in your web pages with JavaScript. The API also provides a number of utilities for manipulating book previews, and is often used together with the other APIs described on this site.

The [Preview Wizard](https://developers.google.com/books/docs/preview-wizard) is a tool built atop the Embedded Viewer API that makes it easier to add preview capabilities to your site by just copying a couple lines of code. This document is intended for more advanced developers looking to customize how the viewer appears on their sites.

## Audience

This documentation is designed for people familiar with
[JavaScript](http://www.ecma-international.org/publications/standards/Ecma-262.htm)
programming and object-oriented programming concepts. You should also be familiar with
[Google Books](https://books.google.com/) from a user's point of view. There are
many [JavaScript tutorials](https://www.google.com/search?q=javascript+tutorials)
available on the Web.

This conceptual documentation is not complete and exhaustive; it is designed to let you quickly start
exploring and developing cool applications with the Embedded Viewer API. Advanced users should may be interested in the
[Embedded Viewer API Reference](https://developers.google.com/books/docs/viewer/reference), which provides comprehensive details
on supported methods and responses.

As indicated above, beginners may want to start with the [Preview Wizard](https://developers.google.com/books/docs/preview-wizard), which automatically generates the code necessary to embed basic previews on your site.

## The "Hello, World" of the Embedded Viewer API

The easiest way to start learning about the Embedded Viewer API is to see a simple example.
The following web page displays a 600x500 preview of
[*Mountain View*](https://books.google.com/books?id=Py8u3Obs4f4C&printsec=frontcover), by Nicholas
Perry, ISBN 0738531367 (part of Arcadia Publishing's "Images of America" series):

```
<!DOCTYPE html "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>Google Books Embedded Viewer API Example</title>
    <script type="text/javascript" src="https://www.google.com/books/jsapi.js"></script>
    <script type="text/javascript">
      google.books.load();

      function initialize() {
        var viewer = new google.books.DefaultViewer(document.getElementById('viewerCanvas'));
        viewer.load('ISBN:0738531367');
      }

      google.books.setOnLoadCallback(initialize);
    </script>
  </head>
  <body>
    <div id="viewerCanvas" style="width: 600px; height: 500px"></div>
  </body>
</html>
```

You can [look at this example](https://developers.google.com/books/docs/viewer/examples/book-simple) and download it to edit and play
around with it. Even in this simple example, there are five things to note:

1. We include the API Loader using a `script` tag.
2. We create a `div` element named "viewerCanvas" to hold the viewer.
3. We write a JavaScript function to create a "viewer" object.
4. We load the book using its unique identifier (in this case `ISBN:0738531367`).
5. We use `google.books.setOnLoadCallback` to call `initialize` when the API has fully loaded.

These steps are explained below.

## Loading the Embedded Viewer API

Using the API Loader framework to load the Embedded Viewer API is relatively simple.
It involves the following two steps:

1. Include the API Loader library:

   ```
   <script type="text/javascript" src="https://www.google.com/books/jsapi.js"></script>
   ```
2. Invoke the `google.books.load` method. The `google.books.load` method takes an optional list parameter specifying a callback function or language, as explained [below](https://developers.google.com/books/docs/viewer/developers_guide#Localization).

   ```
   <script type="text/javascript">
     google.books.load();
   </script>
   ```

### Loading a localized version of the Embedded Viewer API

The Embedded Viewer API uses English by default when displaying textual information such as
tooltips, the names for controls, and link text. If you wish to change
the Embedded Viewer API to properly display information in a particular language, you can add an optional
`language` parameter to your `google.books.load` call.

For example, to display a book preview module with the Brazilian Portuguese interface language:

```
<script type="text/javascript">
  google.books.load({"language": "pt-BR"});
</script>
```

[View example (book-language.html)](https://developers.google.com/books/docs/viewer/examples/book-language)

Currently supported [RFC 3066](https://www.ietf.org/rfc/rfc3066.txt) language codes include af, ar, hy, bg, ca, zh-CN, zh-TW, hr, cs, da, nl, en, fil, fi, fr, de, el, he, hu, is, id, it, ja, ko, lv, lt, ms, no, pl, pt-BR, pt-PT, ro, ru, sr, sk, sl, es, sv, tl, th, tr, uk, and vi.

When using the Embedded Viewer API in languages other than English, we strongly recommend serving your page with a `content-type` header set to `utf-8`, or including an equivalent `<meta>` tag in your page. Doing this helps ensure that characters render correctly across all browsers. For more information, see the W3C's page on [setting the HTTP charset parameter](https://www.w3.org/International/O-HTTP-charset).

## Viewer DOM elements

```
<div id="viewerCanvas" style="width: 600px; height: 500px"></div>
```

For a book to display on a web page, one must reserve a spot for it. Commonly, this is done
by creating a named `div` element and obtaining a reference to
this element in the browser's document object model (DOM).

The example above defines a `div` named "viewerCanvas" and sets its size
using style attributes. The viewer implicitly uses the size of the container to size itself.

## The DefaultViewer object

```
var viewer = new google.books.DefaultViewer(document.getElementById('viewerCanvas'));
```

The JavaScript class that creates and controls a single viewer on the page is
the `DefaultViewer` class. (You may create more than one instance of this class - each
object will define a separate viewer on the page.) A new instance of this class is created
using the JavaScript `new` operator.

When you create a new viewer instance, you specify a DOM node in the
page (usually a `div` element) as a container for the viewer. HTML nodes
are children of the JavaScript `document` object, and
we obtain a reference to this element via the `document.getElementById()` method.

This code defines a variable (named `viewer`) and assigns that variable to a new
`DefaultViewer` object. The function `DefaultViewer()` is known as a [*constructor*](https://en.wikipedia.org/wiki/Constructor_(computer_science))
and its definition (condensed for clarity from the [Embedded Viewer API Reference](https://developers.google.com/books/docs/viewer/reference)) is shown below:

| Constructor | Description |
|---|---|
| DefaultViewer(container, opts?) | Creates a new viewer inside the given HTML `*container*`, which should be a [block-level element](https://www.w3.org/TR/html401/struct/global.html#block-inline) on the page (typically a `DIV`). Advanced options are passed using the optional `*opts*` parameter. |

Note that the second parameter in the constructor is optional---intended for advanced implementations beyond the scope of this document---and it is omitted from the "Hello, World" example.

## Initializing the viewer with a specific book

```
  viewer.load('ISBN:0738531367');
```

Once we've created a viewer via the `DefaultViewer` constructor, it needs to be initializes with a particular book. This initialization
is accomplished with use of the viewer's `load()` method. The `load()` method requires an
`identifier` value, which tells the API what book to show. This method **must** be sent before any other operations are performed
on the viewer object.

If you know of multiple identifiers for a book---the ISBN for the paperback edition, or alternate OCLC numbers---you can pass an array of identifier strings as the first parameter to the `load()` function. The viewer will render the book if there is an embeddable preview associated with *any* of identifiers in the array.

### Supported book identifiers

Like the [Dynamic Links](https://developers.google.com/books/docs/dynamic-links#requestFormat) feature, the Embedded Viewer API supports a number of values to identify a particular book. These include:

ISBN
:   The unique 10- or 13-digit commercial [International Standard Book Number](https://en.wikipedia.org/wiki/International_Standard_Book_Number).  
    Example: `ISBN:0738531367`

OCLC number
:   The unique number assigned to a book by the [OCLC](https://oclc.org) when the book's record is added to the [WorldCat](https://www.worldcat.org) cataloging system.  
    Example: `OCLC:70850767`

LCCN
:   The [Library of Congress Control Number](https://en.wikipedia.org/wiki/Library_of_Congress_Control_Number) assigned to the record by the Library of Congress.  
    Example: `LCCN:2006921508`

Google Books volume ID
:   The unique string Google Books has assigned to the volume, which appears in the URL to the book on Google Books.  
    Example: `Py8u3Obs4f4C`

Google Books preview URL
:   A URL that opens a book preview page on Google Books.  
    Example: `https://books.google.com/books?id=Py8u3Obs4f4C&printsec=frontcover`

These identifiers are often used with other APIs in the Google Books API Family. For example, you can use [Dynamic Links](https://developers.google.com/books/docs/dynamic-links) to render a preview button only if the book is embeddable---and then, when the user clicks the button, instantiate a viewer using the [preview URL returned by the Dynamic Links call](https://developers.google.com/books/docs/dynamic-links#JSONformat). Similarly, you can build a rich browse-and-preview application with the [Books API](https://developers.google.com/books/docs/v1/using), which returns several suitable industry identifiers in its Volumes feeds. Visit the [examples page](https://developers.google.com/books/docs/viewer/examples) to peek at some advanced implementations.

### Handling failed initializations

In some cases, the `load` call may fail. Typically this occurs when the API could not find a book associated with the supplied identifier, when there is no preview of the book available, when the book preview cannot be embedded, or when territorial restrictions prevent the end user from seeing this particular book. You may wish to be alerted of such a failure, so your code can handle this condition gracefully. For this reason, the `load` function allows you to pass an optional second parameter, `notFoundCallback`, which indicates what function should be called if the book could not be loaded. For example, the following code will generate a JavaScript "alert" box if the book could be embedded:

```
function alertNotFound() {
  alert("could not embed the book!");
}

function initialize() {
  var viewer = new google.books.DefaultViewer(document.getElementById('viewerCanvas'));
  viewer.load('ISBN:1234', alertNotFound);
}
```

[View example (book-notfound.html)](https://developers.google.com/books/docs/viewer/examples/book-notfound)

Using this callback, you may decide to show a similar error, or you may choose to hide the `viewerCanvas` element completely. The failure callback parameter is optional, and is not included in the "Hello World" example.

**Note** : Because previews may not be available for all books and for all users, it may be useful to know whether a preview is available *before* you even try to load a viewer for it. For example, you may want to show a "Google Preview" button, page, or section in your UI only if a preview will actually be available to the user. You can do this using the [Books API](https://developers.google.com/books/docs/v1/using) or [Dynamic Links](https://developers.google.com/books/docs/dynamic-links), both of which report whether a book will be available for embedding using the viewer.

### Handling successful initializations

It may also be useful to know if and when a book has loaded successfully. For this reason, the `load` function supports an optional third parameter, `successCallback`, which will be executed if and when a book has finished loading.

```
function alertInitialized() {
  alert("book successfully loaded and initialized!");
}

function initialize() {
  var viewer = new google.books.DefaultViewer(document.getElementById('viewerCanvas'));
  viewer.load('ISBN:0738531367', null, alertInitialized);
}
```

[View example (book-success.html)](https://developers.google.com/books/docs/viewer/examples/book-success)

This callback may be useful if, for example, you only want to show certain elements on your page if the viewer has fully rendered.

<br />

## Showing the viewer on load

```
  google.books.setOnLoadCallback(initialize);
```

While an HTML page renders, the document object model (DOM) is built out, and any external images and scripts are received
and incorporated into the `document` object. To ensure that our viewer is only placed on the page after the page has
fully loaded, the `google.books.setOnLoadCallback` function is used to defer execution of the function that constructs the `DefaultViewer` object. Since `setOnLoadCallback` will only call `initialize` when the Embedded Viewer API is loaded and ready to be used, this avoids unpredictable behavior and ensures control of how and when the viewer is drawn.

**Note:** To maximize cross-browser compatibility, it is strongly recommended that you schedule the viewer load using `google.books.setOnLoadCallback` function, rather than using a `onLoad` event on your `<body>` tag.

## Viewer interactions

Now that you have a `DefaultViewer` object, you can interact with it. The basic viewer object looks and behaves a lot
like the viewer you interact with on the Google Books website and comes with a lot of built-in behavior.

But you can also interact with the viewer programmatically. The `DefaultViewer`
object supports a number of methods that alter the preview state directly. For example, the `zoomIn()`, `nextPage()`,
and `highlight()` methods operate on the viewer programmatically, rather than through user interaction.

The following example displays a book preview that automatically "turns" to the next page every 3 seconds. If the next page is in the
visible part of the viewer, then the viewer pans smoothly to the page; if not, the viewer jumps directly to the top of the next page.

```
function nextStep(viewer) {
  window.setTimeout(function() {
    viewer.nextPage();
    nextStep(viewer);
  }, 3000);
}

function initialize() {
  var viewer = new google.books.DefaultViewer(document.getElementById('viewerCanvas'));
  viewer.load('ISBN:0738531367');
  nextStep(viewer);
}

google.books.setOnLoadCallback(initialize);
```

[View example (book-animate.html)](https://developers.google.com/books/docs/viewer/examples/book-animate)

Note that programmatic calls to the viewer will fail or have no effect until the viewer is fully initialized with a particular book. To ensure you only call such functions when the viewer is ready, use the `successCallback` parameter to `viewer.load` as [described above](https://developers.google.com/books/docs/viewer/developers_guide#Handling_successful_initializations).

For information on all the functions supported by the `DefaultViewer` object, see the [Reference Guide](https://developers.google.com/books/docs/viewer/reference).

## Programming notes

Before you start delving into the Embedded Viewer API, you should take note of
the following concerns to ensure your application works smoothly across
its intended platforms.

### Browser compatibility

The Embedded Viewer API supports recent versions of Internet Explorer,
Firefox, and Safari---and usually other Gecko- and WebKit-based browsers such as
[Camino](http://www.camino.org) and
[Google Chrome](https://www.google.com/chrome) as well.

Different applications sometimes require different behaviors for users with incompatible browsers.
The Embedded Viewer API does not have any automatic behavior when it detects an incompatible browser. Most of the
examples in this document do not check for Browser compatibility, nor do they
display an error message for older browsers. Real applications may do something
more friendly with old or incompatible browsers, but such checks are omitted to make the
examples more readable.

Non-trivial applications will inevitably encounter inconsistencies between browsers and
platforms. Sites such as [quirksmode.org](https://www.quirksmode.org), are
also good resources to find workarounds.

### XHTML and quirks mode

We recommend that you use standards-compliant XHTML on pages that contain the viewer. When browsers see the XHTML
`DOCTYPE` at the top of the page, they render the page in "standards compliance mode," which makes
layout and behaviors much more predictable across browsers. Pages without that definition may render in
"[quirks mode](https://en.wikipedia.org/wiki/Quirks_mode)," which can lead to inconsistent layout.

```
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
```

### A note on the Embedded Viewer API examples

Note that most of the examples in this documentation show only relevant JavaScript code, not the full
HTML file. You can plug the JavaScript code into your own skeleton HTML file, or you can
download the full HTML file for each example by clicking the link after the example.

## Troubleshooting

If your code doesn't seem to be working, here are some approaches
that might help you solve your problems:

- Look for typos. Remember that JavaScript is a case-sensitive language.
- Use a JavaScript debugger. In Firefox, you can use the JavaScript console, the [Venkman Debugger](https://www.mozilla.org/projects/venkman/), or the [Firebug add-on](https://addons.mozilla.org/en-US/firefox/addon/1843). In IE, you can use the [Microsoft Script Debugger](https://msdn.microsoft.com/library/default.asp?url=/library/en-us/sdbug/Html/sdbug_17.asp). The Google Chrome browser comes with [a number of development tools](https://www.google.com/support/chrome/bin/answer.py?answer=95691&query=chrome+debug&topic&type) built right in, including a DOM inspector and a Javascript debugger.