{"id":17214,"date":"2017-05-30T16:15:28","date_gmt":"2017-05-30T13:15:28","guid":{"rendered":"http:\/\/www.webcodegeeks.com\/?p=17214"},"modified":"2017-12-19T12:58:14","modified_gmt":"2017-12-19T10:58:14","slug":"html5-indexeddb-example","status":"publish","type":"post","link":"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/","title":{"rendered":"HTML5 IndexedDB Example"},"content":{"rendered":"<p>One of the headaches of web programming has been the storage and retrieval of user data within an application. Imagine having a database in the server side for storing, for example, some user preferences. That would be a complete overkill, because our web application may not need a server.<\/p>\n<p>HTML5 introduced the IndexedDB technology, a persistent client-side data storage, per each domain. This means that an HTML5 application is able to work with a database (using the JavaScript API) without the need of having any server.<\/p>\n<p>IndexedDB was introduced by the W3C for replacing the deprecated WebSQL, so, if you have ever used this last one, or at least thinking about it, you should dismiss this idea and have a look to the IndexedDB.<br \/>\n[ulp id=&#8217;tgm4cmEWcKUikZNn&#8217;]<br \/>\n&nbsp;<br \/>\nFor this example, the following browsers have been used for testing:<\/p>\n<ul>\n<li>Chromium\u00a056.0.2924.76.<\/li>\n<li>Firefox 52.0.1.<\/li>\n<li>Opera 44.0.<\/li>\n<\/ul>\n<h2>1. Difference between IndexedDB and LocalStorage<\/h2>\n<p>If you have already dealt with client side storage, you may know LocalStorage. At first,\u00a0it may result confusing for the user to choose between LocalStorage and IndexedDB, because, at a first glance, they\u00a0<em>may<\/em> be used for the same purpose: storing data in the client side, in a persistent way. So, we should leave clear the difference between this two technologies, in order to be able to make the most suitable decision for our application when we have to choose a client side storage technology.<\/p>\n<p>The most important difference between LocalStorage and IndexedDB, is that the first one is for storing data in string format in key-value format, and with the second one we can store whole objects in object stores. So, for LocalStorage, we can think about an embedded table with two columns, one for the id and the other for the value in string format; and, for IndexedDB, engine that allows us to have several\u00a0<em>tables\u00a0<\/em>(object stores, as mentioned before) among several databases. Taking this into account, we could say that IndexedDB would be more suitable for more complex data structures, since we can define several storages for several databases (and for several versions of databases) where we can store JavaScript objects; and LocalStorage for the simplest data storage\u00a0possible in string format (note that the option of\u00a0<em>stringifying<\/em> the objects also exists).<\/p>\n<p>There are other differences in the API between these two technologies that of course would affect to the implementation of our applications in one way or another. But the difference we talked about should be the only one to take into account at the time of choosing a technology for storing data in the client side.<\/p>\n<h2>2. Some features of IndexedDB<\/h2>\n<p>Before we start coding, it&#8217;s worth talking about the features of IndexedDB. Otherwise we may get lost just after diving into the code.<\/p>\n<p><strong>IndexedDB allows several databases and several storages for each one<\/strong><\/p>\n<p>We have already mentioned this in the previous section. We can have as many databases as we want, and the same with storages for each database. Each database, apart from its name, it also has a version number that identifies it. Every time we want to alter the structure of our database, we have to upgrade the database version.<\/p>\n<p>For obvious reasons, each database\u00a0<em>belongs<\/em> just to the domain it was created for.<\/p>\n<p><strong>IndexedDB is NOT SQL<\/strong><\/p>\n<p>This is not actually a feature itself, but is something that must be mentioned to avoid usual misconceptions. IndexedDB is not an SQL database. We are not going to define structures like we would do for an SQL database. In any case, the most suitable analogy would be with NoSQL databases.<\/p>\n<p><strong>IndexedDB API is asynchronous<\/strong><\/p>\n<p>This is the most important feature of IndexedDB. This means that <strong>the request to the IndexedDB for opening a database is non blocking<\/strong>.\u00a0Let&#8217;s see with a simple piece of code:<\/p>\n<pre class=\"brush:javascript\">request = indexedDB.open('database');\r\ndatabase = request.result;<\/pre>\n<p>Wouldn&#8217;t be valid. We can&#8217;t use the IndexedDB in that way. Instead, we would have to do the following:<\/p>\n<pre class=\"brush:javascript\">request = indexedDB.open('database');\r\n\r\nrequest.onsuccess = function() {\r\n    database = request.result;\r\n\r\n    \/\/ Now we can perform database operations.\r\n}<\/pre>\n<h2>3.\u00a0Usage<\/h2>\n<p>Now that we have clear the concepts of IndexedDB, we will see it in usage.<\/p>\n<h3>3.1. Creating the database<\/h3>\n<p>The first thing we have to do is retrieve the IndexedDB object, and then perform a request for opening a database of a given name and version (the version is optional).<\/p>\n<p>For this example, we will suppose that we have a database for a catalog of products, for which we will save information such as name, description, price, etc.<\/p>\n<p><em><span style=\"text-decoration: underline;\">indexeddb.js<\/span><\/em><\/p>\n<pre class=\"brush:javascript\">DATABASE_NAME = 'catalog';\r\nDATABASE_VERSION = 1;\r\nSTORE_NAME = 'product';\r\n\r\nvar database;\r\nvar indexedDB = window.indexedDB || window.webkitIndexedDB\r\n    || window.mozIndexedBD || window.msIndexedDB;\r\n\r\nvar request = indexedDB.open(DATABASE_NAME, DATABASE_VERSION);<\/pre>\n<p>Note that, for getting the indexedDB object, we set several fallbacks, each one for each browser engine.<\/p>\n<p>The first we should do after requesting a database, is to bind a function to the onupgradeneeded event. This will be called on database creation, or on version upgrade.<\/p>\n<p><em><span style=\"text-decoration: underline;\">indexeddb.js<\/span><\/em><\/p>\n<pre class=\"brush:javascript\">request.onupgradeneeded = function() {\r\n    console.log('Database upgrade\/creation.');\r\n\r\n    database = request.result;\r\n\r\n    var catalogStore = database.createObjectStore(\r\n        STORE_NAME,\r\n        {\r\n            keyPath: 'id',\r\n            autoIncrement: 'true'\r\n        }\r\n    );\r\n\r\n    catalogStore.createIndex('by_id', 'id');\r\n    catalogStore.createIndex('by_name', 'name');\r\n\r\n    console.log('The database has been created\/updated.');\r\n}<\/pre>\n<p>The first thing we do here is to retrieve the database itself, which is the <code>result<\/code> attribute of the request object retrieved from the IndexedDB object.<\/p>\n<p>Then, we create the store for the catalog, with the\u00a0<code>createObjectStore<\/code> method. The first parameter, the name of the store, is mandatory, but not the second one, the options. In this case, we used the two available options:<\/p>\n<ul>\n<li><code>keyPath<\/code>: this would the &#8220;primary key&#8221; of the storage.<\/li>\n<li><code>autoIncrement<\/code>: this property is for making the key path property increment automatically for each new inserted object, so we don&#8217;t have to care about giving it a value.<\/li>\n<\/ul>\n<p>Even if we already defined a\u00a0primary key, we can create\u00a0and index for it so we can access it by its index, and also for any other property of the object. In this case, we have created for both <code>name<\/code> and <code>id<\/code> properties, with the <code>createIndex<\/code> method. The first parameter is the name of the index itself, which is later needed when retrieving the data, since we need to specify which index we are using; and the second parameter is the property it corresponds to.<\/p>\n<p>All this is will be executed once, unless we change the database version.<\/p>\n<h3>3.2. Inserting data<\/h3>\n<p>We can insert data into the database on creation time, or later. If we do it inside the <code>onupgradeneeded<\/code> scope, we don&#8217;t have to explicitly declare a transaction.<\/p>\n<p><em><span style=\"text-decoration: underline;\">indexeddb.js<\/span><\/em><\/p>\n<pre class=\"brush:javascript\">function insertInitialData(catalogStore) {\r\n    catalogStore.put({\r\n        'name': 'A product',\r\n        'description': 'Description of a product.',\r\n        'price': 10,\r\n    });\r\n\r\n\u00a0    catalogStore.put({\r\n        'name': 'Another product',\r\n        'description': 'Description of another product.',\r\n        'price': 20,\r\n        'subproduct': {\r\n            'name': 'Subproduct of a product'\r\n        }\r\n    });\r\n}\r\n\r\nrequest.onupgradeneeded = function() {\r\n    \/\/ After creating the object storage and indexes...\r\n\r\n    insertInitialData(catalogStorage);\r\n\r\n    \/\/ ...\r\n}<\/pre>\n<p>Note that we are just inserting raw objects, which have properties that have not been even specified in the storage definition.\u00a0If you have just used SQL databases, this may be quite confusing. But, yes, we can insert objects without taking care of which properties they have. We can even nest objects, as with the second product.<\/p>\n<p>If we have a look to the database with the developer tools, we can see its data and structure. The following image shows the database and data we have defined above, using the Chromium developer tools.<\/p>\n<figure id=\"attachment_17268\" aria-describedby=\"caption-attachment-17268\" style=\"width: 763px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/05\/indexeddb.jpg\"><img decoding=\"async\" class=\"wp-image-17268 size-full\" src=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/05\/indexeddb.jpg\" alt=\"\" width=\"763\" height=\"555\" srcset=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/05\/indexeddb.jpg 763w, https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/05\/indexeddb-300x218.jpg 300w\" sizes=\"(max-width: 763px) 100vw, 763px\" \/><\/a><figcaption id=\"caption-attachment-17268\" class=\"wp-caption-text\">1. Visualizing database data with Chromium developer tools<\/figcaption><\/figure>\n<p><strong>Note<\/strong>: the value shown in the column with the hashtag is just an enumeration made by the developer tools, it&#8217;s not a stored value.<\/p>\n<p>If we want to insert data after the creation, we have to do it outside the <code>onupgradeneeded<\/code> scope. There&#8217;s another event available, <code>onsuccess<\/code>, that is triggered after a successful database creation\/upgrade. We will insert some data here:<\/p>\n<p><em><span style=\"text-decoration: underline;\">indexeddb.js<\/span><\/em><\/p>\n<pre class=\"brush:javascript\">request.onsuccess = function() {\r\n    console.log('Successful request for IndexedDB.');\r\n\r\n    database = request.result;\r\n\r\n    var transaction = database.transaction(STORE_NAME, 'readwrite');\r\n    var catalogStore = transaction.objectStore(STORE_NAME);\r\n\r\n    var moreData = [\r\n        {\r\n            'name': 'A third product',\r\n            'description': 'Description of a third product.'\r\n        },\r\n        {\r\n            'name': 'Yet another product',\r\n            'description': 'One last product.'\r\n        }\r\n    ];\r\n\r\n    moreData.forEach(function(data) {\r\n        catalogStore.put(data);\r\n    });\r\n\r\n    transaction.oncomplete = function() {\r\n        console.log('Transaction completed successfully.');\r\n    }\r\n\r\n    transaction.onerror = function(error) {\r\n        console.log('An error occurred during the transaction: ' + error);\r\n    }\r\n}<\/pre>\n<p>Look carefully at the code. First of all, we have to know that this listener is set for the <code>open<\/code> method call on <code>indexedDB<\/code> object. This event will be fired every time, not like <code>onupgradeneeded<\/code>.<\/p>\n<p>After getting the database from the request, first, we create a transaction for the given store (we only have one, <code>product<\/code>) that must exist in the database. As we are going to insert data, the transaction has to provide write access, which is achieved passing the <code>'readwrite'<\/code> value as second parameter.<\/p>\n<p>From this transaction, we get the storage object, for which we will use the <code>put<\/code> method for inserting the data, as we did before. In this case, we have defined an array of objects and iterated it for inserting each one in the database, but is the same as we did before, just calling the <code>put<\/code> method for every object.<\/p>\n<p>We can also define handlers for the success, or failure, of the transaction, defining functions for the <code>oncomplete<\/code> and the <code>onerror<\/code> events.<\/p>\n<p>Take into account that we are inserting several objects for a single transaction. This means that, if a insertion for some of the objects fails, for any reason, a rollback will be made to the state previous to the transaction init. In other words: in an error occurs, the transaction will end with no data inserted, even if it happened for a single object, and other objects could be successfully inserted.<\/p>\n<h3>3.3. Retrieving data<\/h3>\n<p>Of course, we will also see how to retrieve the data.<\/p>\n<p>The initial steps for retrieving data are the same as what we made for inserting it: first, we create a transaction (it&#8217;s necessary also even for read only operations), and we get the storage from it.<\/p>\n<p>Having the storage, we can proceed to the retrieval of the information. For it, we have to get the indexes of the fields we want to make &#8220;query&#8221; for, and then make the request to this index.<\/p>\n<p>Let&#8217;s see a function for querying \u00a0some data:<\/p>\n<p><em><span style=\"text-decoration: underline;\">indexeddb.js<\/span><\/em><\/p>\n<pre class=\"brush:javascript\">function query() {\r\n    var transaction = database.transaction(STORE_NAME, 'readonly');\r\n    var catalogStore = transaction.objectStore(STORE_NAME);\r\n    var idIndex = catalogStore.index('by_id');\r\n    var nameIndex = catalogStore.index('by_name');\r\n\r\n    var request = idIndex.get(1);\r\n\r\n    request.onsuccess = function() { \r\n        console.log(request.result);\r\n    }\r\n\r\n    var request2 = nameIndex.get('Another product');\r\n\r\n    request2.onsuccess = function() {\r\n        console.log(request2.result);\r\n    }\r\n}<\/pre>\n<p>As we can see, we have made different requests on different indexes, just to see that we can used any of the defined indexes. For this, we also have to use the <code>onsuccess<\/code> event, because, remember, the API is asynchronous.<\/p>\n<p>Because of this reason, we have to create another request after the first one, <code>request2<\/code>. If we would use the first request object, we would get a &#8220;The request has not finished&#8221; exception.<\/p>\n<p>The results shown in the console would the the following ones:<\/p>\n<pre class=\"brush:bash\">Object {\r\n    name: \"A product\",\r\n    description: \"Description of a product.\",\r\n    price: 10,\r\n    id: 1\r\n}\r\nObject {\r\n    name: \"Another product\",\r\n    description: \"Description of another product.\",\r\n    price: 20,\r\n    subproduct: Object,\r\n    id: 2\r\n}<\/pre>\n<h3>3.4. Cursors<\/h3>\n<p>Yes! IndexedDB also supports cursors. And they are very easy. For example, the following function would show all the elements of the storage:<\/p>\n<p><em><span style=\"text-decoration: underline;\">indexeddb.js<\/span><\/em><\/p>\n<pre class=\"brush:javascript\">function queryWithCursor() {\r\n    var transaction = database.transaction(STORE_NAME, 'readonly');\r\n    var catalogStore = transaction.objectStore(STORE_NAME);\r\n\r\n    catalogStore.openCursor().onsuccess = function(event) {\r\n        var cursor = event.target.result;\r\n\r\n        if (cursor) {\r\n            console.log(cursor.value);\r\n\r\n            cursor.continue();\r\n        }\r\n    }\r\n}<\/pre>\n<h2>4. Summary<\/h2>\n<p>This example has shown the usage of IndexedDB, the technology introduced with HTML5 for storing data in the client side.\u00a0Actually, IndexedDB is not the only option for storing data in the client side, and that&#8217;s why we made a comparison\u00a0with LocalStorage, the other feature introduced in HTML5, that may result similar at first sight, but which serve for different purposes. Finally, we have seen how to deal with the IndexedDB API, creating databases, inserting data, etc.<\/p>\n<h2>5. Download the source code<\/h2>\n<p>This was an example of HTML5 IndexedDB.<\/p>\n<div class=\"download\"><strong>Download<\/strong><br \/>\nYou can download the full source code of this example here: <strong><a href=\"http:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2017\/05\/HTML5IndexedDBExample.zip\">HTML5IndexedDBExample<\/a><\/strong><\/div>\n","protected":false},"excerpt":{"rendered":"<p>One of the headaches of web programming has been the storage and retrieval of user data within an application. Imagine having a database in the server side for storing, for example, some user preferences. That would be a complete overkill, because our web application may not need a server. HTML5 introduced the IndexedDB technology, a &hellip;<\/p>\n","protected":false},"author":160,"featured_media":914,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12],"tags":[],"class_list":["post-17214","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-html5"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>HTML5 IndexedDB Example - Web Code Geeks - 2026<\/title>\n<meta name=\"description\" content=\"One of the headaches of web programming has been the storage and retrieval of user data within an application. Imagine having a database in the server\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"HTML5 IndexedDB Example - Web Code Geeks - 2026\" \/>\n<meta property=\"og:description\" content=\"One of the headaches of web programming has been the storage and retrieval of user data within an application. Imagine having a database in the server\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/\" \/>\n<meta property=\"og:site_name\" content=\"Web Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/webcodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2017-05-30T13:15:28+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2017-12-19T10:58:14+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/html5-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Toni\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Toni\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/\"},\"author\":{\"name\":\"Toni\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/54a7be647b0b871cff41cbf3d2a95966\"},\"headline\":\"HTML5 IndexedDB Example\",\"datePublished\":\"2017-05-30T13:15:28+00:00\",\"dateModified\":\"2017-12-19T10:58:14+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/\"},\"wordCount\":1724,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/html5-logo.jpg\",\"articleSection\":[\"HTML5\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/\",\"name\":\"HTML5 IndexedDB Example - Web Code Geeks - 2026\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/html5-logo.jpg\",\"datePublished\":\"2017-05-30T13:15:28+00:00\",\"dateModified\":\"2017-12-19T10:58:14+00:00\",\"description\":\"One of the headaches of web programming has been the storage and retrieval of user data within an application. Imagine having a database in the server\",\"breadcrumb\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/#primaryimage\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/html5-logo.jpg\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/html5-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.webcodegeeks.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"HTML5\",\"item\":\"https:\/\/www.webcodegeeks.com\/category\/html5\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"HTML5 IndexedDB Example\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"name\":\"Web Code Geeks\",\"description\":\"Web Developers Resource Center\",\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.webcodegeeks.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/webcodegeeks\",\"https:\/\/x.com\/webcodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/54a7be647b0b871cff41cbf3d2a95966\",\"name\":\"Toni\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/21c1661474c78b4757355b8beef9ab1d14f490ee3a3e67392f4e618d36643d4c?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/21c1661474c78b4757355b8beef9ab1d14f490ee3a3e67392f4e618d36643d4c?s=96&d=mm&r=g\",\"caption\":\"Toni\"},\"url\":\"https:\/\/www.webcodegeeks.com\/author\/julen-pardo\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"HTML5 IndexedDB Example - Web Code Geeks - 2026","description":"One of the headaches of web programming has been the storage and retrieval of user data within an application. Imagine having a database in the server","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/","og_locale":"en_US","og_type":"article","og_title":"HTML5 IndexedDB Example - Web Code Geeks - 2026","og_description":"One of the headaches of web programming has been the storage and retrieval of user data within an application. Imagine having a database in the server","og_url":"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/","og_site_name":"Web Code Geeks","article_publisher":"https:\/\/www.facebook.com\/webcodegeeks","article_published_time":"2017-05-30T13:15:28+00:00","article_modified_time":"2017-12-19T10:58:14+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/html5-logo.jpg","type":"image\/jpeg"}],"author":"Toni","twitter_card":"summary_large_image","twitter_creator":"@webcodegeeks","twitter_site":"@webcodegeeks","twitter_misc":{"Written by":"Toni","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/#article","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/"},"author":{"name":"Toni","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/54a7be647b0b871cff41cbf3d2a95966"},"headline":"HTML5 IndexedDB Example","datePublished":"2017-05-30T13:15:28+00:00","dateModified":"2017-12-19T10:58:14+00:00","mainEntityOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/"},"wordCount":1724,"commentCount":0,"publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/html5-logo.jpg","articleSection":["HTML5"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/","url":"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/","name":"HTML5 IndexedDB Example - Web Code Geeks - 2026","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/#primaryimage"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/html5-logo.jpg","datePublished":"2017-05-30T13:15:28+00:00","dateModified":"2017-12-19T10:58:14+00:00","description":"One of the headaches of web programming has been the storage and retrieval of user data within an application. Imagine having a database in the server","breadcrumb":{"@id":"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/#primaryimage","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/html5-logo.jpg","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/html5-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.webcodegeeks.com\/html5\/html5-indexeddb-example\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.webcodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"HTML5","item":"https:\/\/www.webcodegeeks.com\/category\/html5\/"},{"@type":"ListItem","position":3,"name":"HTML5 IndexedDB Example"}]},{"@type":"WebSite","@id":"https:\/\/www.webcodegeeks.com\/#website","url":"https:\/\/www.webcodegeeks.com\/","name":"Web Code Geeks","description":"Web Developers Resource Center","publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.webcodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.webcodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.webcodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/webcodegeeks","https:\/\/x.com\/webcodegeeks"]},{"@type":"Person","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/54a7be647b0b871cff41cbf3d2a95966","name":"Toni","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/21c1661474c78b4757355b8beef9ab1d14f490ee3a3e67392f4e618d36643d4c?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/21c1661474c78b4757355b8beef9ab1d14f490ee3a3e67392f4e618d36643d4c?s=96&d=mm&r=g","caption":"Toni"},"url":"https:\/\/www.webcodegeeks.com\/author\/julen-pardo\/"}]}},"_links":{"self":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/17214","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/users\/160"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/comments?post=17214"}],"version-history":[{"count":0,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/17214\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media\/914"}],"wp:attachment":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media?parent=17214"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/categories?post=17214"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/tags?post=17214"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}