diff --git a/README.md b/README.md
index e09a184..00e5341 100644
--- a/README.md
+++ b/README.md
@@ -25,11 +25,15 @@ sitemap:
   path: sitemap.xml
   template: ./sitemap_template.xml
   rel: false
+  tags: true
+  categories: true
 ```
 
 - **path** - Sitemap path. (Default: sitemap.xml)
 - **template** - Custom template path. This file will be used to generate sitemap.xml (See [default template](/sitemap.xml))
 - **rel** - Add [`rel-sitemap`](http://microformats.org/wiki/rel-sitemap) to the site's header. (Default: `false`)
+- **tags** - Add site's tags
+- **categories** - Add site's categories
 
 ## Exclude Posts/Pages
 
diff --git a/index.js b/index.js
index 6a147cb..3e99d77 100644
--- a/index.js
+++ b/index.js
@@ -5,7 +5,9 @@ const { extname } = require('path');
 
 hexo.config.sitemap = Object.assign({
   path: 'sitemap.xml',
-  rel: false
+  rel: false,
+  tags: true,
+  categories: true
 }, hexo.config.sitemap);
 
 const config = hexo.config.sitemap;
diff --git a/lib/generator.js b/lib/generator.js
index 78357fe..ae71a01 100644
--- a/lib/generator.js
+++ b/lib/generator.js
@@ -5,16 +5,18 @@ const template = require('./template');
 
 module.exports = function(locals) {
   const { config } = this;
+  const { sitemap, skip_render } = config;
+  const { path, tags: tagsCfg, categories: catsCfg } = sitemap;
   const skipRenderList = [
     '**/*.js',
     '**/*.css'
   ];
 
-  if (Array.isArray(config.skip_render)) {
-    skipRenderList.push(...config.skip_render);
-  } else if (typeof config.skip_render === 'string') {
-    if (config.skip_render.length > 0) {
-      skipRenderList.push(config.skip_render);
+  if (Array.isArray(skip_render)) {
+    skipRenderList.push(...skip_render);
+  } else if (typeof skip_render === 'string') {
+    if (skip_render.length > 0) {
+      skipRenderList.push(skip_render);
     }
   }
 
@@ -27,18 +29,21 @@ module.exports = function(locals) {
     });
 
   if (posts.length <= 0) {
-    config.sitemap.rel = false;
+    sitemap.rel = false;
     return;
   }
 
-  const xml = template(config).render({
+  const data = template(config).render({
     config,
-    posts
+    posts,
+    sNow: new Date(),
+    tags: tagsCfg ? locals.tags.toArray() : [],
+    categories: catsCfg ? locals.categories.toArray() : []
   });
 
   return {
-    path: config.sitemap.path,
-    data: xml
+    path,
+    data
   };
 };
 
diff --git a/lib/template.js b/lib/template.js
index 41a2c56..bc0e101 100644
--- a/lib/template.js
+++ b/lib/template.js
@@ -18,6 +18,7 @@ module.exports = function(config) {
     return encodeURL(str);
   });
 
+  // Extract date from datetime
   env.addFilter('formatDate', input => {
     return input.toISOString().substring(0, 10);
   });
diff --git a/sitemap.xml b/sitemap.xml
index 9c13a14..59af8bb 100644
--- a/sitemap.xml
+++ b/sitemap.xml
@@ -10,4 +10,29 @@
     {% endif %}
   </url>
   {% endfor %}
+
+  <url>
+    <loc>{{ config.url | uriencode }}</loc>
+    <lastmod>{{ sNow | formatDate }}</lastmod>
+    <changefreq>daily</changefreq>
+    <priority>1.0</priority>
+  </url>
+
+  {% for tag in tags %}
+  <url>
+    <loc>{{ tag.permalink | uriencode }}</loc>
+    <lastmod>{{ sNow | formatDate }}</lastmod>
+    <changefreq>daily</changefreq>
+    <priority>0.6</priority>
+  </url>
+  {% endfor %}
+
+  {% for cat in categories %}
+  <url>
+    <loc>{{ cat.permalink | uriencode }}</loc>
+    <lastmod>{{ sNow | formatDate }}</lastmod>
+    <changefreq>daily</changefreq>
+    <priority>0.6</priority>
+  </url>
+  {% endfor %}
 </urlset>
diff --git a/test/index.js b/test/index.js
index 5c78bfa..e8f29db 100644
--- a/test/index.js
+++ b/test/index.js
@@ -3,8 +3,14 @@
 require('chai').should();
 const Hexo = require('hexo');
 const cheerio = require('cheerio');
-const { encodeURL } = require('hexo-util');
+const { deepMerge, encodeURL } = require('hexo-util');
 const { ready, transform } = require('camaro');
+const sitemapCfg = {
+  path: 'sitemap.xml',
+  rel: false,
+  tags: true,
+  categories: true
+};
 
 const p = async xml => {
   await ready();
@@ -19,9 +25,11 @@ const p = async xml => {
 
 describe('Sitemap generator', () => {
   const hexo = new Hexo(__dirname, {silent: true});
-  hexo.config.sitemap = {
-    path: 'sitemap.xml'
-  };
+  hexo.config.sitemap = sitemapCfg;
+  const defaultCfg = deepMerge(hexo.config, {
+    sitemap: sitemapCfg
+  });
+
   const Post = hexo.model('Post');
   const Page = hexo.model('Page');
   const generator = require('../lib/generator').bind(hexo);
@@ -36,6 +44,8 @@ describe('Sitemap generator', () => {
       {source: 'bar', slug: 'bar', updated: 1e8 + 1},
       {source: 'baz', slug: 'baz', updated: 1e8 - 1}
     ]);
+    await Promise.all(data.map(post => post.setTags(['lorem'])));
+    await Promise.all(data.map(post => post.setCategories(['ipsum'])));
     posts = data;
     data = await Page.insert([
       {source: 'bio/index.md', path: 'bio/', updated: 1e8 - 3},
@@ -46,20 +56,67 @@ describe('Sitemap generator', () => {
     locals = hexo.locals.toObject();
   });
 
+  beforeEach(() => {
+    hexo.config = deepMerge(hexo.config, defaultCfg);
+  });
+
   it('default', async () => {
     const result = generator(locals);
+    const { items } = await p(result.data);
 
     result.path.should.eql('sitemap.xml');
     result.data.should.eql(sitemapTmpl.render({
       config: hexo.config,
-      posts: posts
+      posts,
+      sNow: new Date(),
+      tags: locals.tags.toArray(),
+      categories: locals.categories.toArray()
     }));
 
-    const { items } = await p(result.data);
-    items.forEach((element, index) => {
-      element.link.should.eql(posts[index].permalink);
-      element.date.should.eql(posts[index].updated.toISOString().substring(0, 10));
-    });
+    for (let i = 0; i < posts.length; i++) {
+      items[i].link.should.eql(posts[i].permalink);
+      items[i].date.should.eql(posts[i].updated.toISOString().substring(0, 10));
+    }
+  });
+
+  it('tags', async () => {
+    const { data } = generator(locals);
+    const { items } = await p(data);
+
+    const result = items.filter(({ link }) => link.includes('tags'));
+
+    const check = result.length > 0;
+    check.should.eql(true);
+  });
+
+  it('tags - disable', async () => {
+    hexo.config.sitemap.tags = false;
+    const { data } = generator(locals);
+    const { items } = await p(data);
+
+    const result = items.filter(({ link }) => link.includes('tags'));
+
+    result.length.should.eql(0);
+  });
+
+  it('categories', async () => {
+    const { data } = generator(locals);
+    const { items } = await p(data);
+
+    const result = items.filter(({ link }) => link.includes('categories'));
+
+    const check = result.length > 0;
+    check.should.eql(true);
+  });
+
+  it('categories - disable', async () => {
+    hexo.config.sitemap.categories = false;
+    const { data } = generator(locals);
+    const { items } = await p(data);
+
+    const result = items.filter(({ link }) => link.includes('categories'));
+
+    result.length.should.eql(0);
   });
 
   describe('skip_render', () => {