Blog Handbook

Welcome to the GitLab Blog Handbook!

On this page

GitLab Blog

Our Blog is orchestred by the Product Marketing and the Developer Relations Marketing Team.


Objectives & Purposes

Important considerations

The blog is our main publishing outlet. Let's do our best to show what's best!

Posts Formats

We aim to publish content multiple times a week, with a reliable publishing schedule. The user will most likely have a pleasant experience if we combine multiple posts formats, trying never to be too much repetitive. Repetition is boring. We'll alternate between the following formats:

Blog Content

It is important to have in mind that a good post can considerably reach a lot of people and acquire more users. With well written articles, we have the opportunity to expose and explore, in a friendly language, all the features GitLab provides.

Try to think about what our users might have interest in reading before picking up a subject to work on. And remember, our users do not need to be super advanced programmers. They can be newbie folks with limited experience, students, technology enthusiasts, and people not used to Git, version control and continuous integration. That's why we need to define a target audience before start writing.

Our audience will probably be interested in the topics listed below.

Product-specific topics

User Stories

Do you have a better idea? Don't hesitate, create an issue with your proposal and we'll be glad to look into it.


Technical Aspects

All blog posts should always have an author name. When applicable, add a section "Acknowledgments" to the end of the post to thank contributors.

Publishing process for GitLab Team members

  1. Choose a topic
  2. Define the target audience, knowledge level and system requirements (example)
  3. Create outlines (a few items describing what you want to discuss along the post)
  4. Submit an issue on the blog posts issue tracker containing the previous items
  5. Mention @amara for feedback on your proposal and on your outlines
  6. Amara will evaluate the priority and estimate a due date for publishing
  7. Write the post according to the Professional Writing Techniques
  8. Submit your draft as a WIP MR (work in progress merge request) in the GitLab website project
  9. You'll get reviewed and feedback from our Marketing Team:
    • Assign Marcia (@virtuacreative) for a general review
    • When done, Marcia will reassign to Axil (if technical), or Amara (if non-technical)
    • Amara gives the last check and approval to merge
  10. Your post will be published
  11. Marketing Team will post on social media (Twitter/Facebook)

Not a GitLab Team member? Check the process for Community Writers below.

Publishing process for Community Writers

For our community writers, we will follow the Scalable Writing System described below.

  1. Community Writer - choose a subject:
  2. Content Marketing - analyse the proposal:
    • Amara will evaluate the writer's sample and discuss anything necessary before start writing
    • When the guest writer is approved to get started, Amara will leave a comment "@username, you got it!" and assign the issue to the writer
  3. Community Writer: prepare local environment and submit the article
  4. Reviewers:
    • Amara will take a first look to approve the article for review, and assign Marcia for the first review
    • When first review is finished, Marcia will assign Axil for a detailed technical review
    • When finished, Axil will reassign the merge request to Amara, who will follow the check list and approve the content for publishing
  5. Content Marketing: publish
    • Content Marketing will place the date for publishing
    • Amara will merge and tweet/Facebook
  6. Content Marketing / Account Ops: pay the writer
    • Amara email the writer to wire the money
    • Guest writer will get paid

Important: make sure the last section of the post is "About the guest author", describing in two or three sentences the author's background on the post's subject. It should be written by the author him/herself. Examples: check this post and this post for reference.

Blog Post Issue Tracker

To keep things clear for everyone, we assume:


Check out our styles guidelines.

Forked project

Before you write, make sure you forked www-gitlab-com, cloned to your computer, and were able to preview it locally by running bundle exec middleman. Before making any change, create a new branch git checkout -b branchname cloned from master.

Check list before merging

Reviewer - check these before you publish:

It takes about 7-10 mins for the blog post to appear as published after merged. As soon as it's live, check the post for broken links using this tool (or similar): Fix anything before sharing in any communication channel or social media network.

After the blog post is published we should tweet immediately from the GitLab Twitter account, and schedule follow up tweets and LinkedIn and Facebook. Validate the Twitter Card before tweeting!

Get inspired


We invite and encourage guest writers and also offer compensation through the Community Writers program.

Blog Style Guidelines

This style guide is specifically for blog posts on


Every blog post must start from the documentation, never the opposite. Thus, if the subject you want to write about is not documented, please consider contributing to the docs first, or bring it to our attention by creating a new issue, so we can take action to make it documented properly.

Before writing, make sure you've read through this Style Guidelines, the Blog directives, the Technical Aspects, the Professional Writing Techniques and the Markdown Style Guide.

Before submitting your post for review, make sure you:


The blog posts are located in the project www-gitlab-com, under /source/posts/.

The file name must have this structure: The date can be changed just before publishing, so don't worry if it is accurate or not. Future dates are accepted, in case you have estimated the publishing date, which is defined by the Marketing Team.

In all file names, prefer using dashes - than underscores _. Do not leave blank spaces in file names, ever.


All posts are written in markdown Kramdown. Please read through the Markdown Style Guide for reference.


The post frontmatter is the first part of any post. It is standard and cannot be changed, so please make sure to provide the correct information, and do not add nor remove anything from the default template:

title: "This is the post title"
author: Firstname Lastname
author_twitter: userID
categories: technical overview
image_title: '/images/blogimages/post-cover-image.jpg'
description: "Short description for the blog post" # included in August, 2016

New frontmatter! Social Media information: twitter_image and description!

title: "This is the post title"
author: Firstname Lastname
author_twitter: userID
categories: technical overview
image_title: '/images/blogimages/post-cover-image.jpg'
description: "Short description for the blog post"
twitter_image: '/images/tweets/post-screenshot-image.png'


Make sure the post title represents very well the subject, and make it as short as possible. Do the same for headings.

Author Name

Use the author's full name. If the name has special chars, type it within double quotes "Full Name".

Twitter Handle

Don't worry if you don't have an account on Twitter. Leave the field author_twitter blank.


Use only one of the following categories per post. Do not capitalize nor pluralize them, nor change any letter, otherwise you'll create another category, which is somenthing we don't want to do unpurposely.

We'll improve it, but by now you can find posts under the same category by navigating to Dashes will be automatically added to multi-word categories and all of them will be lowercased in the URL. For example, the category "GitLab CE" will be available under

If you think we are missing an important category, please let us know by adding a comment to this issue:

Cover Image

Do not leave the post without a cover image (image_title), unless you have a strong reason to do so. Read more about it below.


The description meta tag is important for SEO, also is part of Facebook Sharing and Twitter Cards. We set it up in the post frontmatter, as a small summary of what the post is about.

It's a way of making the post title shorter, then add complementary information in the description. It's not meant to repeat the post title, use your creativity to describe what's in the post. Try to use about 70 to 100 chars in one sentence.

It is mandatory for all the new posts, and it has been included in the default post frontmatter generated by the command rake new_post.

Use this syntax:

description: "This is an example description for a blog post."

See the following section "Social Media Info" for more information.

Social Media Info

When you post a link on Facebook or Twitter, either you can see only a link, or a full interactive card, which displays information about that link: title, description, image and URL.

For Facebook these cards are configured via OpenGraph Meta Tags. Twitter Cards were recently setup for our website as well.

Please compare the following images illustrating post's tweets.

A complete card will look like this:

Twitter Card example - complete

An incomplete card will look like this:

Twitter Card example - incomplete

Note that the first post has a specific description and the image is a screenshot of the post's cover image, taken from the Blog landing page. This screenshot can be taken locally when previewing the site at localhost:4567/blog/.

All the screenshots for twitter_image should be pushed to the www-gitlab-com project at /source/images/tweets/ and must be named after the post's file name. If the post is called, the tweet image must be named hello-world.png (or .jpg).

For the second post above, note that the tweet image is the blog post cover image itself, not the screenshot. Also, there's no description provided in the frontmatter, so our Twitter Cards and Facebook's post will present the fall back description, which is the same for all

The description is a mandatory field, though the twitter_image is optional. Whenever possible, provide the post screenshot image to make it easier to our audience to identify a GitLab Blog Post straight away when scrolling their feed.

You can check and preview them with the Twitter Card Validator and the Facebook Debugger.


Comments are present in all posts by default. Set it to false only if you have a strong reason to do so (comments: false). They are our best source of feedback on posts.


The variable date: yyyy-mm-aa hh:mm:ss is not necessary in the frontmatter anymore, unless you want to set an specific time. If you do, just make sure that the date in the file name matches with the date in the frontmatter, otherwise the build will fail. It's going to be necessary when publishing more than one post per day. The latest will stay on the top of the blog landing page.

Create a new post

You can create a new post however you prefer: adding a new file to /source/posts/, duplicating an existing post, or using the command line, which is the safest way to do so. Just is type into your terminal (opened in your local project directory):

rake new_post

Hit enter or return, then you'll be prompted to enter the post title. Type in the title exactly as you want it, for example "Hello World - I'm a new post" and rake will take care of the file name for you. Then you just open the file, fill in with your name, Twitter handle, and the post category, then you'll be good to start writing.

Body structure

Just below the frontmatter, start writing your post, including the sections as follows:

If the article is part of a series, make sure to link back among all articles in the series to each one after they get published.


When writing tutorials, be clear on the steps needed to follow through. Break the tutorial into small steps and the steps into tasks, but bare in mind that long lists of steps have the downside of being hard to follow and refer back to. So, consider serializing posts if needed.


As explained on the Professional Writing Techniques, always provide source for your statements.


Illustrate your examples, with code blocks or screenshots. Be consistent along your examples. E.g., if you are using a generic URL to exemplify your steps, be consistent and keep it, throughout the post.

Important security point: Do not expose your personal details by using your real tokens or security credentials. Use placeholders such as [project's CI token] stub instead. Or blur them if displayed on screenshots.


Creating images

Preparing images

For the blog, images should be cropped in a 1.7 width/height pixel proportion (ideally 1275px x 750px) so the image doesn't get clipped when displayed as a lead image in the blog list. This includes the cover image. Compress the image, for example using or any other image editor. To preserve the harmony along the post, try to keep all the images with the same width (e.g., the ones used in this post).

Image shadow

It is important to highlight the image so that it can easily be recognized as image, and not as part of the text. The way we use is adding a CSS custom class called shadow. You do that by adding the markup {: .shadow} right besides the image markup:

![Image Alternative Text](/path/to/image.png){: .shadow}

Where to place images

Images used to illustrate articles should be placed in the /source/images/blogimages/ directory. Unless they are 'free to use' lead images from Unsplash, which should be placed in the /source/images/unsplash directory.

Naming images

If you are using a set of images, create a new directory under /source/images/blogimages/, name it according to your post's title and add all the images there. For example, if your post has a file name, your new folder should be named /my-awesome-post/.

If you use just a couple images, you can add them directly to /source/images/blogimages/, but make sure they begin with the same name as you post's. This way it's easy to anyone know which image is related to each post. Name the files according to the previous example. So, following the same logic, your cover image would be named my-awesome-post-cover.png, accessed under /source/images/blogimages/my-awesome-post-cover.png.

Cover image

Choose a cover image for your post. Try any public domain resource that reflects somehow your post's subject. In the absence of an image, use one of these:

Creating GIFs

Animated GIFs are very useful to illustrate short dynamic processes, which might be easier to understand with this kind of resource. There are a few ways to create animated GIFs, one of them is using Giphy Capture, a light-weight app for Mac.

Avoid GIFs with a huge file size, they will be difficult to load for users with bad internet connection. In those cases, you can either cut the GIFs in smaller pieces, or record a video, or use a sequential image (e.g., the ones used in this post).

Read more on Making Gifs in the Product Handbook.

GitLab Specific Terms

Blog Content Calendar

In the spreadsheet below you'll find posts recently published (From 2016, June 1st on), together with some other posts that are queued for writing, reviewing and publishing. This calendar was implemented not long ago and is still being improved, it's opened to eventual changes and contributions.

The link attached to the post title will lead you to the Merge Request, while the link on "Published" will lead you to the post itself.

Note: Main Content Pillars, subjects, categories, names, content distribution, and other specific matters are still being discussed and polished.