Blog Handbook

Welcome to the GitLab Blog Handbook!

On this page

GitLab Blog

Our Blog is managed by the Content Team.


Objectives & Purposes

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




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

Types of Blog Posts

In our Blog, you will find 8 types of blog posts:

Release Posts

Every 22nd of each month, GitLab promotes a new release of our main instances: GitLab CE and GitLab EE. runs on GitLab EE, therefore, it gets the same enhancement GitLab EE does. We use our blog to communicate the new features, upgrades, and alterations. These posts are created by the Product Team or by the developers themselves, and they're reviewed by a lot of team members involved.

Release posts target the entire GitLab community, and they are usually cheered by the everyone. They are special posts, we love them, and we hope you love them too!

Once and awhile, you'll find patch-release posts as well. They are prepared by the same team as the major release posts, to communicate new features, rollbacks, and anything else relevant for the community.

When we find important security issues, we publish security release posts in the same way. They communicate relevant changes that reflect in the system security and related subjects.

Examples: release posts, security release posts.

Team Member's 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.

Events Posts

Every 1st working day of the month we publish a post communicating the events for that following month. They are written by our Field Marketing Manager & Swag Queen, Emily Kyle, who always has a lot of fun stories to share with us. Stay tuned for the next event near you, so you can pass by our booth to say hello, grab your swag, and share your thoughts with Emily and other team members!

Events posts are also submitted to General Reviews.

Community Posts

If you are not a GitLab Team member, you're also very welcome to write for us. There are a few aspects to consider, described on the section Community Writers.

If you are a GitLab happy customer or a happy user, we'll be delighted to see your post in our Blog! And to make you even happier, we compensate you for your contributions, under specific circumstances. Note that this is the only type of post that offers financial compensation.

The community posts follow a particular publishing process.

If you are looking for examples for community posts, check Setting up GitLab CI for iOS projects, Hosting on with GitLab Pages, and Tutorial: Securing your GitLab Pages with TLS and Let's Encrypt.

Note: if you want to describe your own product, and how to use it with GitLab, we'll be happy to publish your article as a GitLab Guest Post, not as a community post. If you are a GitLab official partner, we'll be happy to see your post too! Please check, we have specific procedures for both Guest Posts and Partner Posts.

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 according to the Publishing Process for Guest Writers.

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.

Partner Posts

These posts are specific for official GitLab Partners. The drill for these posts is flexible, and can be adapted case by case. We usually write the post and publish according to a schedule pre-defined by the GitLab Marketing Team and the partner.

Examples: integration with Koding, Digital Ocean, Yubico, Mattermost, Pivotal Cloud Foundry.

Ghost Posts

Ghost posts are part of a special category of posts, written by ghostwriters contracted by GitLab with this specific purpose. They are based on interviews with GitLab Executives, reviewed by GitLab Team members and Blog Editors, and approved by the GitLab Team member assigned as author of the post.

Check the section Publishing Process for Ghost Writers below for more details.


These are great posts written by our community and published originally by another communication channel. The writer is invited to reach us via Twitter or email ( asking to repost his/her article in our blog. Your post will be evaluated by our Editors and, if accepted, will follow a particular publishing process for crossposts.

If we find your post ourselves, we'll reach you out and ask for your approval for cross-posting it. If you are interested and agree with the publishing process and the quick review, your post will get reposted.

Everyone wins when we crosspost: we win, as it's interesting for our community; and you win, as your post will gain extra visibility across the web!

Examples: Moving to GitLab! Yes, it's worth it!, Building an Elixir Release into a Docker image using GitLab CI - Part 1, Applying GitLab Labels Automatically.

GitLab Community Writers Program

Read through the terms on the Community Writers Program.

Publishing Processes

Blog Editorial Team

The publishing process is simple and is conducted for our Blog Editors and reviewers. Check their roles:

General Publications

  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 (or pick up one of the existing issues)
  5. Mention Erica @Lindberg for feedback on your proposal and on your outlines
    • If necessary, Erica will assign Marcia for evaluating your proposal and outlines
    • Erica will ask for an ETA on your first draft
    • Erica will evaluate the priority, and estimate a due date for publishing (issue due date)
    • Erica will give you a thumbs up 👍 to start writing (@mention you saying "you're good to go!")
  6. Write the post according to the Professional Writing Techniques and to the Markdown Guide
  7. Submit your draft as a WIP MR (Work in Progress Merge Request) to the GitLab website project
  8. You'll get reviewed and feedback from our Editorial Team
  9. Your post will be published
  10. Marketing Team will promote on social media (Twitter/Facebook)

General Reviews

Read the section Performing Reviews for further details.

Publishing process for Community Writers

For our community writers, we will follow the Scalable Writing System described below, coordinated by the Blog Editorial Team.

  1. Community Writer - choose a subject:
  2. Content Marketing - analyses the proposal:
    • Erica will evaluate the writer's sample and discuss anything necessary before the author start writing
    • If necessary, Erica will assign Marcia for evaluating your proposal and outlines
    • If the issue isn't already labeled with the compensation labels ($100, $200, TOP PRIORITY), Erica will define the compensation the post is worth and attribute the correct label.
    • When the community writer is approved to get started, Erica will leave a comment "@username, you got it!" and label the issue on it and community post.
    • Erica will ask for an ETA on your first draft
    • Erica will evaluate the priority, and estimate a due date for publishing (issue due date)
  3. Community Writer: prepare your local environment and submit the article
  4. GitLab: Erica will make sure the MR description contains the issue closing pattern (Closes #xxx) and the label community post, and start the review process
  5. GitLab - General Review
  6. GitLab - When your post gets ready:
    • Marcia will change your MR from your branch into master to another branch feature-branch
    • Marcia will merge your MR into the new feature-branch and:
      • Create a new MR to master, which closes the blog post issue (link to the original MR)
      • Preview the post locally
      • Upload the preview screenshot to the new MR thread
    • Marcia and Erica can make any necessary adjustments to the post in the new MR (date, typos, grammar, broken links, and other changes that won't affect substantially the content)
    • Erica will place the final date for publishing and create the copyedit for social media (140 chars tops, including the post link)
  7. On the publishing date:
    • Marcia or Erica will merge your post into master
    • Erica or Marcia will promote in social media: Twitter and/or Facebook
  8. After the publishing date: compensate the writer (when compensation applies)
    • Author send an email to Erica (at requesting the compensation for the post, adding a link to the issue, to the original MR, and to the published post
    • Erica replies the writer to start the process to wire the money
    • Community writer will get paid

Important: make sure the last section of the post is "About the Community 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.

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.

Sample: your writing sample can be any technical article or post already written by yourself, or a sample of ~200 words on a related topic.

Outlines: draw the post outlines, which is the sequence of topics to write about, as a skeleton with the headings you propose to follow along in your post. The blog editors will discuss them with you, and review if necessary.

Publishing process for Guest Writers

To be included

Publishing process for Ghost Writers

To be included

Publishing process for CrossPosts

To be included

Labels Strategy

Every blog post should carry a label, in both issues and merge requests:

Labels Exclusive for Community Posts

The following labels define the compensation the post is worth it, corresponding to its length, importance to our Content Strategy, and to our community. They should be applied to every compensated community post, only in the Blog Posts issue tracker.

Important: these exclusive labels should be added by the Blog Editors only. If you find a post that you think should receive one of these labels, please @mention one of the editors in the issue or MR. They will evaluate your request and attribute the proper label.

Blog Post Issue Tracker

To keep things clear for everyone in the issue tracker, we assume:

Performing Reviews

To be included


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 posts. Just make sure to 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 (double quotes included):

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

Check the Social Marketing Handbook for more information.

Social Media Sharing Image

It's the image which will be displayed on social media feeds. It's defined in the post frontmatter, and it's not mandatory, but recommended.

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. Otherwise, make sure it's included, to make it easier to our audience to identify a GitLab Blog Post straight away when scrolling their feed.

The standard procedure for this image is:

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

twitter_image for the blog

**If your post is called, the twitter_image should be named hello-world.png.

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


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.

Writing Style

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

GitLab content primarily follows AP Style, which is searchable online. 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.


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

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:

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