Blog Handbook

Welcome to the GitLab Blog Handbook!

On this page

GitLab Blog

Our Blog is managed by the Marketing Team. Other team members are encouraged to contribute blog posts, but please see the Publishing processes section and follow the steps there to get started.


Blog endboss

Rebecca Dodd is the blog endboss.

If the post author does not know who can do a final review or merge their post they can assign it to Rebecca. A post author must get at least one review from someone in their immediate team and use a spelling and grammar checker before assigning the MR to Rebecca.

Publishing Processes

Blog Editorial Team

Third-party posts

Blog posts concerning third parties or partners, whether they are to be published on the GitLab blog or externally, should be proposed to the blog editorial team before agreeing.

  1. Create an issue in the blog posts project and ping @rebecca and @erica.
  2. If technical input is required, we will ask for instructions from the third party, otherwise it is at the discretion of the blog editorial and technical writing teams whether or not to go forward.

Team posts

  1. Choose a topic
  2. Define the target audience, knowledge level and system requirements (example)
  3. Create an outline (a few items describing what you want to discuss along the post)
  4. Create an issue in the blog posts project and ping @rebecca so she can factor it into the publishing schedule
  5. Write the post according to the Professional Writing Techniques and to the Markdown Guide
  6. Submit your draft as a WIP MR (Work in Progress Merge Request) to the GitLab website project
  7. Get reviewed by your team, and address their feedback
  8. Get feedback and review from the editorial team and assign to @rebecca to merge
  9. Ask @evhoffmann to promote on social media (Twitter/Facebook)

Important: never write your draft on pre-styled text editors like Google Docs or Microsoft Word. They don't use the same character encoding as markdown does (UTF-8), and it may cause issues when rendering markdown into HTML. Please use one of the recommended code editors.

Publishing process for Community Writers

The Community Writers Program has changed. Please check the new Terms and Conditions.

Objectives & purposes

What content should go on the blog?

The blog is:

The documentation is different to the blog in that it is:

Anatomy of a blog post

Later sections of this handbook contain granular examples of different types of posts and how to write them, but a few broad things should be true of all posts, no matter the writer or the topic.

Big picture




Post formats

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

Blog content

Try to think about what our community might be interested in reading before picking up a subject to work on; you should always begin by identifying your target audience for the post. Here are some example topics & categories:

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 a real author name. When applicable, add a section "Acknowledgments" to the end of the post to thank contributors.

Types of blog posts

Release Posts

Find out more about them on the release posts handbook!

Examples: release posts, security release posts.

Team Members' Posts

Whenever we have something interesting to talk about, we encourage our own team members to write their stories. And there are a lot of awesome ones! Even if you are not a writer, you are very welcome to write, and our reviewers will be happy to help you with the language, the technical aspects, the markup, the concepts and whatever else you might need.

If you are part of the GitLab Team, please contribute! The review process is simple, please take a look at the General Publishing Process below.

Guest Posts

These posts are specific for community members that want to write about their own tools, features, and software integrations with GitLab. They can be written by the owners, executives or any team members of those companies, and will be reviewed by the GitLab Blog Editors..

For instance, we've had the post on Integrating GitLab with Microsoft Azure. It was written by one of Microsoft's employees, then reviewed and polished by our own Technical Writers. A similar process occurred to publish the post on Continuous Delivery with GitLab and Convox.

Note: we do not offer compensation for Guest Posts.

GitLab Community Writers Program

Read through the new terms and conditions for the Community Writers Program, announced on April 2017.


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.

Checklist 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.

Get inspired

Blog style guidelines

This style guide is specifically for blog posts on


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_gitlab: username # included in February, 2017
author_twitter: Twitter username
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, description, CTA buttons, author_gitlab, and guest!

title: "This is the post title"
author: Firstname Lastname
author_gitlab: username
author_twitter: Twitter username
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' # optional
cta_button_text: 'Watch the <strong>XXX release webcast</strong> live!' # optional
cta_button_link: '' # optional
guest: true # required when the author is not a GitLab Team Member
ee_cta: false # required only if you do not want to display the EE-trial banner
keywords: [ keyword1, keyword2 ] # optional
twitter_text: "Text to tweet" # optional

The following sections describe each entry of the frontmatter.


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". handle

Add the author's handle (username only, without "@"). If your username is johndoe, accessible under, this field should be filled as follows:

author_gitlab: johndoe

This field is required.

Introduced in January, 2017.

Twitter handle

Add the author's Twitter handle (username only, without "@"). If your username is johndoe, accessible under, this field should be filled as follows:

author_twitter: johndoe

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

Twitter Text

Add a text to tweet in twitter_text. If no text is provided it will use post's title.

twitter_text: "We just released a new feature!"


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 (double quotes included):

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

Check the Social Marketing Handbook for more information.


The kewwords are used both as a meta tag is important for SEO and as hashtags for the twitter sharable section.

keywords: [ keyword1, keyword2]

Social Media Sharing Image

It's the image which will be displayed on social media feeds. It's defined in the post frontmatter.

twitter_image: '/images/tweets/image-name.png'

Whenever you want to display exactly the cover image in social media feeds, don't add a twitter_image to the frontmatter. The blog cover image you used will render just as-is in your social timeline via the card automatically produced on Twitter & Facebook. If you want to preview what your card will look like, or verify that the link you're sharing has cards enabled, use Twitter's card validator tool. This is the approach we use for blog posts with titles longer than one line when viewed on our blog homepage. The release post may be an exception.

Whenever the blog post title fits on one line when viewed on the blog homepage, you may choose to add a twitter image. The standard procedure for this image is:

*This is the portion to take the screenshot from (purple line):

twitter_image for the blog

You can also use another image for social sharing.

For further information, read the Social Media Sharing section at the Social Marketing Handbook.

Call to action (CTA)

There are two new possible entries in the frontmatter:

cta_button_text: 'Watch the <strong>XXX release webcast</strong> live!'
cta_button_link: ''

The first entry is text, referring to the link added to the second one. Therefore, always use them together.

The examples above link to a release webcast, but you can add any pair of text and link to this CTA. Use it wisely.

Do not include any UTM parameters to the link. Always wrap their values with quotes.

The final result is a red button over the cover image of the post.

Hero CTA preview

The CTA entry is optional; if you don't need to add any CTA to the hero, just omit both entries, leaving the frontmatter without them.

This option was introduced in January/2017.

EE-Trial Banner

ee-trial banner

To not display the EE-trial banner on the blog post, set ee_cta to false in the frontmatter:

ee_cta: false

It is set to true by default, so there's no need to add ee_cta: true to the frontmatter.

Use it wisely; the EE-trial banner is important for Lead Gen.


The variable guest indicates whether the author is a guest (anyone who's not a GitLab Team member). It should be only included in the frontmatter when that's the case. Technically, it's a conditional variable (true or false) to link the author's name their profile in the Team page.

For Guest Posts, Partner Posts, and Crossposts, it must be present:

guest: true

For Team Posts, please do not add it at all (instead of setting it to false).

Introduced in February, 2017.


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, 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.

Writing style

At GitLab, we use American English as the standard written language.

GitLab content primarily follows AP Style, which is searchable online. However we use sentence case for all titles and subheadings, as it is easier to apply consistently and helps readers to scan titles more easily.

Any questions that cannot be answered by the AP Stylebook may be resolved by referring to the Chicago Manual of Style. To learn about GitLab's advanced formatting system, check out our Markdown Guide.

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.


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. All images should be at least smaller than 1MB. JPEGs tend to be smaller than PNGs so use JPEGs when possible. 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).

The only images accepted for are public domain images and screenshots. Whenever you choose an image which is not a screenshot, add a link to the original image to the merge request description and as an HTML comment:

<!-- image: image-url -->

Do the same for cover images, adding a link to the original image to the end of the post as a comment and to the MR description:

<!-- cover image: image-url -->

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:

Please add a reference to the cover image source, owner, and licence at the end of the blog post, even if it doesn't require attribution:


Cover image: ["Image title"](link-to-original-image) by [owner name and surname](link), licensed
under [CC X](link-to-licence).
{: .note}

If the image does not have a title, default to the following format:


[Cover image](link-to-original-image) by [owner name and surname](link), licensed
under [CC X](link-to-licence).
{: .note}

The cover image has the following proportions:

Try to have them harmonically aligned with the title, which overlays the background image in both cases.

To crop the image, use the size of 1275x750 px. If you want to align the background image with the title overlay, use the widescreen proportion.

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

Quick guide for release posts

Update (April, 2017): check the release posts handbook.