A blog theme for VuePress by Ktquez 🤘

Overview

vuepress-theme-ktquez

A blog theme for VuePress by Ktquez 🤘 🤘

Vuepress does not yet have native support for blogs, but this theme has some practices and customizations to turn into a blog.

Vuepress theme ktquez starter

I know the theme configuration seems like a lot of work though, I've created a boilerplate with the settings and structure of folders organized, just clone the repository and change the information for your blog, modify the images and start using.

https://github.com/ktquez/vuepress-theme-ktquez-starter


Table of Contents

Installation

npm install -S vuepress-theme-ktquez

Configuration

The theme customization is done through the .vuepress/config.js
For your reference, you can see the config.js of my blog.

module.exports = {
  theme: 'ktquez',
  ...
  locales: {              // Example with multiple locales, but usually works only with a single locale
    '/': {
      lang: 'en'
    },
    '/pt/': {
      lang: 'pt-br'
    },
    '/es/': {
      lang: 'es'
    }
  },
  themeConfig: // example below
  configureWebpack () {
    return {
      resolve: {
        alias: {
          '@public': path.join(__dirname, './public')
        }
      }
    }
  }
}

themeConfig

MADE WITH VUEPRESS ', footer: { nav1: { title: 'NAVIGATION 1', items: [ { label: 'ABOUT', path: '/about/' // Use "link" for external links and "path" for internal links }, ... ] }, nav2: { title: 'NAVIGATION 2', items: [ { label: 'Slack Group', link: 'https://my_group.slack.com/' // Use "link" for external links and "path" for internal links }, ... ] } }, social: [ { name: 'twitter', // Look for the "social icon section" below link: 'https://www.twitter.com/ktquez' }, ... ] }, '/pt/': { languages: { // Used in the drop down of languages label: 'Portuguese', shortname: 'PT' }, ... // the rest of the properties of this locale are the same as the example above, but with information for that language }, '/es/': ... }, disqus: 'MY_DISQUS_SHORTNAME', url: 'https://my_doamin.com', cdn: '', // If there is a CDN, put the bucket link here. blackWhite: true, // Active toggle for Nocturne mode topNavigation: true, // Turn on the navigation menu above the header searchMaxSuggestions: 7, // Maximum result per search responsive: { active: true, // Turn on responsive images on the cover of the post ext: 'png', breakpoints: [320, 427, 524, 680] // Breakpoints used for picture media tag }, share: { facebook: { appId: '', version: 'v3.1' } }, elevator: { duration: 4000, mainAudio: '/music/elevator.mp3', endAudio: '/music/ding.mp3' } }, ">
themeConfig: {
  locales: {
    '/': {
      languages: {                              // Used in the drop down of languages
        label: 'English', 
        shortname: 'EN' 
       }, 
      translation: {},                          // Look for the "translations section" below
      logo: { 
        name: 'MY_LOGO_FILENAME', 
        ext: 'png', 
        alt: 'My description about logo' 
      },
      share: { 
        facebookCaption: 'MY_CAPTION_FB_SHARE', 
        twitterVia: 'MY_TWITTER_NICKNAME' 
      },
      newsletter: {
        provider: 'mailchimp',                  // Currently supports mailchimp
        action: 'link_form_action_mailchimp'
      },
      copy: '2018 © Ktquez play -  MADE WITH VUEPRESS ',
      footer: {
        nav1: {
          title: 'NAVIGATION 1',                
          items: [
            {
              label: 'ABOUT',
              path: '/about/'                         // Use "link" for external links and "path" for internal links
            },
            ...
          ]
        },
        nav2: {
          title: 'NAVIGATION 2',                 
          items: [
            {
              label: 'Slack Group',
              link: 'https://my_group.slack.com/'     // Use "link" for external links and "path" for internal links
            },
            ...
          ]
        }
      },
      social: [ 
        {
          name: 'twitter',                        // Look for the "social icon section" below
          link: 'https://www.twitter.com/ktquez'
        },
        ...
      ]
    },
    '/pt/': {
      languages: {                              // Used in the drop down of languages
        label: 'Portuguese', 
        shortname: 'PT' 
      },
      ...  // the rest of the properties of this locale are the same as the example above, but with information for that language
    },
    '/es/': ...
  },
  disqus: 'MY_DISQUS_SHORTNAME',
  url: 'https://my_doamin.com',
  cdn: '',                              // If there is a CDN, put the bucket link here.
  blackWhite: true,                     // Active toggle for Nocturne mode
  topNavigation: true,                  // Turn on the navigation menu above the header
  searchMaxSuggestions: 7,              // Maximum result per search
  responsive: {
    active: true,                       // Turn on responsive images on the cover of the post
    ext: 'png',
    breakpoints: [320, 427, 524, 680]   // Breakpoints used for picture media tag
  },
  share: {
    facebook: { appId: '', version: 'v3.1' }
  },
  elevator: { duration: 4000, mainAudio: '/music/elevator.mp3', endAudio: '/music/ding.mp3' }
},

Translations of the theme

The texts that are in the theme are translated and currently the theme has included the translations for EN and PT, any other language you will use, just add the key: value in the translation property that the theme will do rest for you.

themeConfig: {
  locales: {
    '/es/': {
      languages: { label: 'Spanish', shortname: 'ES' },
      translation: {
        back: 'Atrás',
        home: 'Home',
        author: 'Autor',
        ...
      }
    },
    '/fr/': {
      languages: { label: 'French', shortname: 'FR' },
      translation: {
        back: 'arrière',
        home: 'Page d\'accueil',
        author: 'auteur',
        ...
      }
    }
  }
}

For you to see all the key: value used in the theme, just access this example

Newsletter

To make the newsletter form appear, simply add the action of your newsletter.

themeConfig: {
  locales: {
    ...
    '/': {
      ...
      newsletter: {
        provider: 'mailchimp',
        action: 'MY_ACTION_FOR_ENGLISH_USERS'
      },
    },
    '/pt/': {
      ...
      newsletter: {
        provider: 'mailchimp',
        action: '' // Does not display the form if you leave an empty string
      }
    }
  }
  ...
}

Responsive post cover

To improve UX and performance, the blog supports responsive images through breakpoints.

themeConfig: {
  ...
  responsive: {
    active: true, // Turn on responsive images on the cover of the post
    ext: 'png',
    breakpoints: [320, 427, 524, 680] // Breakpoints used for picture media tag
  },
  ...
}

With the example above, you need to insert the images with the final ,w_XXX, for example:

If your post is: /posts/my-first-post.md
Your images should be in public/images/posts/__YEAR__/__MONTH__/ and with the following sizes:

  • public/images/posts/2018/8/my-first-post,w_320.png
  • public/images/posts/2018/8/my-first-post,w_427.png
  • public/images/posts/2018/8/my-first-post,w_524.png
  • public/images/posts/2018/8/my-first-post,w_680.png
  • public/images/posts/2018/8/my-first-post.png

If you don't want to use responsive images, simply disable and to use public/images/posts/2018/8/my-first-post.png

Structure directores (Suggestion)

├── .vuepress
├── index.md
├── about/
|   ├── README.md
├── contact/
|   ├── README.md
├── categories/
|   ├── README.md
|   ├── category1.md
|   ├── category2.md
├── posts/
|   ├── README.md
|   ├── my-first-post.md
├── pt/
|   ├── index.md
|   ├── sobre/
|   |   ├── README.md
|   ├── contato/
|   |   ├── README.md
|   ├── categorias
|   |   ├── README.md
|   |   ├── categoria1.md
|   |   ├── categoria2.md
|   ├── posts/
|   |   ├── README.md
|   |   ├── meu-primeiro-post.md
├── es/
...

There are key: value in translations of routes, if you do not have your language or want to rename, just add in translation translation

Frontmatter

Home

---
view: home
title: my title
description: my description
meta:
  - property: og:image
    content: https://my_domain.com/share/my-site-image-share.png
  - name: twitter:image
    content: https://my_domain.com/share/my-site-image-share.png
---

Post

---
view: post
layout: post
lang: pt-br             # Lang by locale of post (required)
author: ktquez          # Nickname author 
title: My First post
description: 
excerpt:
cover: true             # If true it displays the cover image of the post, if it has no image, leave it as false
coverExt:               # If you want to specify the image extension, PNG is the default
coverAlt:               # cover alt text
demo:                   # If you have demo link, insert here, to display the demo demo button in post
categories:
  - vuejs               # slug of category
  - javascript
tags: 
  - tag1                # You may feel free to create tags, it will be used on the category page
  - tag2
  - tag3
created_at: 2018-08-22 11:00 
updated_at: 2018-08-22 11:00
meta:
  - property: og:image
    content: https://my_domain.com/images/posts/my-first-post.png
  - name: twitter:image
    content: https://my_domain/images/posts/my-first-post.png
---

For more examples, just see the posts of Ktquez play

Category

---
view: category
lang: pt-br       # Lang by locale of post (required)
order: 1          # Order of display in list categories
top: true         # Include category in navigation Top
title: Vue.js
description: 
excerpt: 
slug: vuejs       # Used in post yaml for the array of categories
---

Author

---
view: author
lang: pt-br                       # Lang by locale of post (required)
title: Articles by Alan Ktquez
description: 
name: Alan Ktquez
nickname: ktquez                  # Used in post yaml to indicate the author
role: Web developer
avatar: /authors/avatar_author.png
created_at: 2018-08-22
social:
  - name: twitter
    url: https://twitter.com/author
  - name: github
    url: https://github.com/author
  - name: site
    url: https://author_site.com
meta:
  - property: og:image
    content: https://my_domain.com/authors/avatar_author.png
  - name: twitter:image
    content: https://my_domain.com/authors/avatar_author.png
---

Page

---
view: page
title: 
description: 
excerpt: 
ctaContact: true    # Show call-to-action to contact page. If there is no contact page, set it to false
---

Override CSS (Stylus)

To overwrite the theme variables to customize colors and etc, simply create a file in .vuepress/override.styl, por exemplo:

$primaryColor = #AE4967
$accentColor = #35495E

$color1 = #41b883
$colorImageFallback = $accentColor

$firstFooterColor = #35495E
$secondFooterColor = #263647

To see all the variables, access this link

The best pratice of accessibility includes

The theme uses some plugins from the Vue A11y project

In addition to good practices such as:

  • Nocturne mode
  • Customization of alternative texts in images;
  • Card posts with descriptive links using aria-labelledby;
  • Among others

Lazy-load

It is possible to delay media loading using the global component .

In any markdown files you can to use this component, for example load a Youtube video

">
<lazy-load tag="iframe" :data="{ src: 'https://www.youtube.com/watch?v=lIv1ItUzktc' }" />

Or for images:

">
<lazy-load tag="img" :data="{ src: 'https://octodex.github.com/images/stormtroopocat.jpg', alt: 'The Stormtroopocat' }" />

This component uses the IntersectionObserver API to display the elements. You can check this link for support of this API

If you want to use and support older browsers, you can use this polyfill

And more

Anaytics campaign in posts

All posts sharing icons links are included in analytics campaign parameters.
?utm_source=SOCIALNAMECLICKED&utm_medium=share&utm_campaign=single-post

With this you can analyze the interaction and shares of your posts.

Fonts

The theme have as fonts:

To overwrite the fonts, simply use the .vuepress/style.styl. Ver doc vuepress

This theme adopts the strategy to load Web fonts using FontFaceObserver

Assets

You can copy some assets from the public folder of the theme, they server for you to configure some images as well as files to turn your blog into a PWA (for example the file manifest.json).

Ads

You can also insert ads in the blog, which are displayed in the sidebar of the home page and the right side of the post. Ads are built through an array of objects that we can insert into each themeConfig locale, example taken from my personal blog

For example:

themeConfig: {
  locales: {
    ...
    '/': {
      ...
      ads: [
        {
          text: 'Did you know that Udemy has more than 300 web development courses for only R $ 21.99?',
          link: 'http://bit.ly/web-development-udemy',
          image: {
            src: '/web-development-english.png',
            alt: 'Illustration of a user studying online'
          },
          by: {
            text: 'udemy.com',
            link: 'http://bit.ly/all-courses-udemy'
          }
        }
      ],
    },
    '/pt/': {
      ...
      ads: [
        {
          text: 'Você sabia que a Udemy tem mais de 300 cursos de desenvolvimento web por apenas R$ 21,99?',
          link: 'http://bit.ly/desenvolvimento-web-em-portugues-udemy',
          image: {
            src: '/web-development-portugues.png',
            alt: 'Ilustração de um usuário estudando online'
          },
          by: {
            text: 'udemy.com',
            link: 'http://bit.ly/all-courses-udemy'
          }
        }
      ]
    }
  }
  ...
}

Note, avoid placing words that indicate that it is an ad, to avoid blocking Adblock

Tools

Tools that can help you:

  • Slugify - Slug generation, for your links and filenames;
  • Responsive breakpoints - Responsive image breakpoints generator for cover images;
  • SEO Counter - Is an online word and character counter with SEO rules for title and description;

License

MIT

Contributing

  • Check the open issues or open a new issue to start a discussion around your feature idea or the bug you found.
  • Fork repository, make changes and send a pull request

If you want a faster communication, find me on @ktquez

Thank you

Comments
  • Responsive post cover doesnt appear in post.

    Responsive post cover doesnt appear in post.

    hey, I'm again sorry I have a problem with Upload image in post. when I set in a public folder and create folder year & month and makes a responsive image is still not found, I have set cover: true and already set responsive section like in your setting and still got nothing.

    screenshot_2019-01-20_14-32-37

    can you help me? thanks

    opened by AnasR7 4
  • NaN date on card and Post page

    NaN date on card and Post page

    First of all, thanks for sharing this beautiful theme!

    I found a bug on Safari, regarding how time is parsed. All dates are NaN, see picture to understand more:

    image

    Same page on Chrome:

    image

    Operating System: macOS Mojave 10.14.2 Browser Version: Safari 12.0.2

    opened by gabrielboliveira 3
  • Is there a way to have a one-page as a home and list of posts to an specific blog section?

    Is there a way to have a one-page as a home and list of posts to an specific blog section?

    Hello. Your theme looks very awesome, thanks! My idea is to use it as a one-page for a personal project, and I would like to use vuepress with your theme as a one-page site with blog section. Can I? How?

    opened by albertosgz 1
  • Where can i put my cover image?

    Where can i put my cover image?

    An excellent theme for vuepress. But I'm having trouble in how to replace the cover image of each posts And I failed to find some useful information in the README,could you tell me how can I put my cover image of each posts, thank you

    opened by RobinChen95 0
  • fix #13 set base is /doc but img src still is /

    fix #13 set base is /doc but img src still is /

    if i set .vuepress/config.js base options, file path is 404。so i set $withBase to fix。 this is my first pr。Please give me more advice. last, i get sorry for i add semi for this files.

    opened by maczyt 0
  • set base is /doc but img src still is /

    set base is /doc but img src still is /

    First of all, thank you for your theme。

    I had a problem. i set .vuepress/config.js base /doc

    next, i run vuepress dev ., then picture 404. for img src still is /。

    opened by maczyt 2
  • [WIP] Creating a documentation

    [WIP] Creating a documentation

    The idea is to categorize the most diverse settings of the theme, as well as to create tutorials to teach how to configure it.

    If someone had a hard time configuring it, I'd like to know how I can best the usability of themes features.

    Thanks for using.

    opened by ktquez 0
Owner
Alan Ktquez
Frontend developer • Vue.js • HTML & A11y enthusiast.
Alan Ktquez
🖼️ An Elegant VuePress Theme, inspired by @vue/theme.

VT An Elegant VuePress Theme, inspired by @vue/theme . ?? Live Documentation ?? VuePress Docs With This Theme Features Compatibility: fully compatible

ULIVZ 58 Dec 11, 2022
💥 A simple and beautiful vuepress Blog & Doc theme.

?? A simple and beautiful vuepress Blog & Doc theme.

vuepress-reco 264 Jan 3, 2023
Shopify Foundation Theme is modern Shopify theme built with Shopify Theme Lab, Vue and Tailwind CSS.

Modern Shopify theme using Shopify Theme Lab, Liquid, Vue and Tailwind CSS ??

UI Crooks 218 Jan 4, 2023
Vuepress v2+ dynamic-title-plugin: add a dynamic title in your vuepress

vuepress-plugin-dynamic-title-v2 ?? Add a dynamic title in your vuepress! Document: moefy-vuepress Live demo: notev Dependencies vuepress version vuep

tianyake 1 May 6, 2022
A theme for VuePress 2

vuepress-theme-mix About The Project VuePress Theme Mix is a minimalistic theme that is designed and developed for VuePress 2. It's deeply customized

Gavin 49 Jan 5, 2023
A custom vuepress theme with mermaid and plantuml, katex and vue components.

Personal Documentation Theme for VuePress Currently, completely refactoring code for vuepress v1, all components should be compatible. This is the Vue

David Li 58 Oct 10, 2022
A minimalist vuepress theme, compatible with hexo YAML front matter syntax.

A minimalist vuepress theme, compatible with hexo YAML front matter syntax.

BLANK 19 Dec 14, 2022
Personal Documentation Theme for VuePress

Personal Documentation Theme for VuePress Currently, completely refactoring code for vuepress v1, all components should be compatible. This is the Vue

CH 0 Jul 30, 2019
VitePress theme base on @vue/theme, more practical and comprehensive.

VitePress theme base on @vue/theme, more practical and comprehensive.

alex.wei 4 Sep 1, 2022
Contact Us widget generator. plugin for Vuepress 可以自动生成联系我们按钮的插件

Vuepress Plugin: Contact Us Form This plugin will automatically put a floating button at the left-bottom corner, once it's clicked, a contact us form

Justin Wang 6 Sep 23, 2022
A Unicorn theme for Slidev slides based on dawntraoz.com design.

slidev-theme-unicorn A Unicorn theme for Slidev. This theme is based on dawntraoz.com website design

Alba Silvente Fuentes 44 Nov 16, 2022
A Penguin 🐧 theme for Slidev

This theme is based on my personal brand, but it can be easily use and customized for your own.

Alvaro Saburido 103 Dec 16, 2022
A Slidev Theme for my talks about Vue.js

slidev-theme-vuetiful A Vue-inspired theme for Slidev. Live demo: https://slidev-theme-vuetiful.netlify.app/ Features Pretty Vue Theme Subtle Animatio

Thorsten Lünborg 57 Dec 23, 2022
LightDM theme inspired in Void Linux (without any reason)

LightDM Void Theme I tried Void Linux and got super excited to create a lightdm theme inspired in Void. There's actually no relation with Void Linux,

Jezer Mejía 16 Jan 3, 2023
A front-end multi-theme solution based on sass

A front-end multi-theme solution based on sass

Tom McFly 1 May 13, 2022
🚀一款简洁高效的VuePress知识管理&博客(blog)主题

??一款简洁高效的VuePress知识管理&博客(blog)主题

Evan Xu 2.9k Jan 4, 2023
Blog Site Using Nuxt , Vite And Tailwind Css

NuxTailwind Blog Site Using Nuxt , Vite And Tailwind CSS. Key Features • How To Use • Download • Credits • Related • License View On Desktop 1024x768

kalana kithmina 10 Nov 18, 2022
Content-theme-blog-minimal is a standalone theme for creating your blog within minutes!

content-theme-blog-minimal content-theme-blog-minimal is a standalone theme for creating your blog within minutes! Demo: https://dumptyd.github.io/con

Saad 12 Aug 28, 2022
Vue 2.0 blog template, includes vue-blog-template, vue-blog-admin, vue-blog-h5, node-server-api, remember to star

简介 vue-blog-template 是基于vue2.0,包含了vue-blog-template(PC版)、vue-blog-h5(H5版)、vue-blog-admin(blog后台管理系统)、node-server-api(blog服务端API),用于个人博客的开发和管

Jason Chen 25 Dec 2, 2022
A VuePress 1.x theme that supports a dark theme, multiple color themes, and other useful features.

Yuu A VuePress theme that supports a dark theme, multiple color themes, and other useful features. Extended upon the default VuePress theme with some

Sanctuary 72 Dec 26, 2022