{% include anchor.html edit="true" title="Plugins" hash="plugins" %} {% include alert/start.html variant="info"%} {% markdown %} **This section covers _authoring_ plugins.** For a list of third-party plugins, see [Plugins](/external.html), or for a list of first-party plugins that you can use to customize the PouchDB build, see [Custom Builds](/custom.html). {% endmarkdown %} {% include alert/end.html%} Writing a plugin is easy! The API is: {% highlight js %} PouchDB.plugin({ methodName: myFunction }); {% endhighlight %} This will add a `db.methodName()` to all databases, which runs `myFunction`.It will always be called in context, so that within the function, `this` refers to the database object. There is a [PouchDB Plugin Seed project](https://github.com/pouchdb/plugin-seed), which is the fastest way to get started writing, building and testing your very own plugin. #### Example Usage: {% highlight js %} PouchDB.plugin({ sayHello : function () { console.log("Hello!"); } }); new PouchDB('foobar').sayHello(); // prints "Hello!" {% endhighlight %} Alternatively, instead of passing in an object to `.plugin()`, you can pass in a function that takes the `PouchDB` object and performs whatever operations you want on it. You can use this to load multiple plugins, add adapters, or attach event listeners to the `PouchDB` object. #### Example Usage: {% highlight js %} PouchDB.plugin(function (PouchDB) { PouchDB.hello = 'world'; }); console.log(PouchDB.hello); // prints "world" {% endhighlight %} (Most likely, if you are writing a PouchDB plugin, you will export either the object-style or the function-style plugin, so that your users can then attach it to their PouchDB object.) #### Load Plugins from require() You can load plugins into PouchDB when you load it via `require()`. {% highlight js %} var greet = {sayHello: function() { console.log("Hello!"); }}; var PouchDB = require('pouchdb').plugin(greet); var db = new PouchDB('foobar'); db.sayHello(); // prints "Hello!" {% endhighlight %} You can chain plugins, as well: {% highlight js %} var greet = {sayHello: function() { console.log("Hello!"); }}; var manners = {thank: function(name) { console.log("Thank you, " + name); }}; var PouchDB = require('pouchdb') .plugin(greet) .plugin(manners); var db = new PouchDB('foobar'); db.sayHello(); // prints "Hello!" db.thank('Mom'); // prints "Thank you, Mom" {% endhighlight %} #### Example Plugin: Intercept Updates A useful feature of plugins is to intercept updates before they are stored in PouchDB. In this way, a plugin might validate that the data is correct for the application, or even alter documents before they are committed to the database. The best way to intercept all updates to a PouchDB database is to **override the `bulkDocs()` method**. All changes to PouchDB documents ultimately pass through the `bulkDocs()` method. For example, a call to `put()` will become become a `bulkDocs()` call with a "batch" of one document. Because PouchDB guarantees to plugin authors that all data changes ultimate happen via `bulkDocs()`, it is the ideal place for an application or plugin to intercept updates. {% highlight js %} // Keep a reference to the "upstream" function. var pouchBulkDocs = PouchDB.prototype.bulkDocs; PouchDB.plugin({bulkDocs: validBulkDocs}); function validBulkDocs(body, options, callback) { if (typeof options == 'function') { callback = options options = {} } if (Array.isArray(body)) { var docs = body; } else { var docs = body.docs; } // All documents must have a .name field. for (var i = 0; i < docs.length; i++) { if (!docs[i].name) { var id = doc._id || '(no _id given)'; return callback(new Error('Document is missing .name field: ' + id)); } } // All documents check out. Pass them to PouchDB. return pouchBulkDocs.call(this, docs, options, callback); } {% endhighlight %} The above plugin would return an error if anything ever attempts to store an unnamed document, including documents which change during replication. Note: this is a very, very simple validation example. It does not behave, for example, like the Apache CouchDB `validate_doc_update()` API.