The GitLab blog is managed by @rebecca the Managing Editor.
#content
for questions, see #content-updates
for updates on most recently published articles.If you'd like to write about something for the GitLab blog, please use the guide below to decide which process to follow:
If your proposed blog post includes any of the following:
Please see the PR handbook for instructions on submitting a request via an announcement
issue template in the Corporate Marketing project. This is to ensure we have an opportunity to identify the best channel to share your news before starting work on a blog post draft.
If your proposed post doesn't meet the criteria for an announcement, please follow the instructions below to pitch your idea to the Editorial team. This process is intended to ensure the Editorial team is spending the bulk of their time working on posts that get results and align with the goals for the blog.
If you prefer, you can submit a complete blog post to the GitLab Unfiltered blog without pitching first. The Unfiltered blog is monitored weekly for posts to feature on the main blog. Unfiltered posts are not shared on GitLab's official social media handles.
Please open an issue in the gitlab.com/gitlab-com/www-gitlab-com using the Blog post
template. Include a short summary of your proposed blog post where indicated, and add the Blog::Pitch
label to ensure your pitch is triaged. Unless your post is urgent, there is no need to ping the Editorial team as pitches with that label are reviewed weekly.
If you hope to publish on a specific date or within a specific timeframe, please allow at least three weeks' lead time from the date you open your issue and ping @rebecca
immediately, as the Editorial calendar fills up quickly and we cannot guarantee there will be a slot for your post without adequate notice. Please give a rationale for your proposed publish date in the issue description so the team can prioritize accordingly.
If you prefer, you can start drafting your blog post right away, before getting approval. All this means is that you may need to edit your post based on feedback from the Editorial team, or publish directly to Unfiltered instead. If you're not concerned about whether you publish on the main blog or Unfiltered, this may suit you.
If you do not intend to write the post yourself but are just suggesting an idea you think would be worth pursuing, please make this clear in your issue description.
Many people throughout GitLab the company and community contribute to the blog. Our pitching process ensures we can prioritize submissions so we don't overwhelm our audience with too much content at once, and to help our contributors craft their ideas in a way that will get views. After reviewing years of data, we know what type of content is likely to get views and what is unlikely to resonate. We want to help every contributor maximize the impact of their contribution.
Data shows that more blog posts does not equal more views. In fact, too much content can have a negative impact on our traffic. The pitching process allows us to review each article and schedule it at the most appropriate time. We've found that publishing ~3 articles per week is the most effective publishing cadence for the GitLab blog.
If you don't want to pitch a blog post, but would rather publish directly to the GitLab Unfiltered blog, please visit the Unfiltered blog handbook to get started.
Note: All blog posts related to the Board must be reviewed by legal prior to publication. Please indicate if this applies to your pitch by checking the relevant box in your issue description. Ideally, Legal should be looped in as early as possible.
Note: If you're planning to write a tutorial post describing how to do something with GitLab, please ensure that the relevant documentation exists first before you write a blog post about it. A blog post should not replace documentation, but should add more information, context, and color around a technical subject, linking back to the documentation for full instructions.
The team will be assessing pitches against the following criteria:
To give your idea the best chance of being accepted, be sure to demonstrate how your pitch meets the criteria above. It may also help to think about the following:
Showing how your proposed blog posts meets the criteria and that you've given thought to the considerations above will give your pitch the best chance of being accepted.
Below are links to blog post proposals that demonstrate the value the post will offer to the reader:
The Editorial team will review issues with the label Blog::Pitch
every Monday, and a team member will respond on your issue to let you know whether to move forward with your draft.
If your pitch isn't accepted, no problem! The Editorial team will suggest that you submit your post to the GitLab Unfiltered blog instead. The Unfiltered blog is monitored weekly for posts to feature on the main blog.
Blog post
merge request template for your MR and ensure it is set to close the associated issue automatically.Note for the Content team: If your blog post is already scheduled and appears on the blog calendar please submit your MR and associated issue directly to @rebecca or @skassabian for review.
First, please see If you want to share news/an update or are seeking feedback to check if you need to open an announcement request issue.
If you have already followed those directions in the PR handbook and the Corporate Communications and Editorial teams have decided that a blog post is the best way to communicate your announcement, please follow the process below.
Blog post
template and applying the priority
label. Even if you do not have a draft or a confirmed publish date, it's important to open the issue as far in advance as possible and ping @rebecca so she knows it is coming and can prioritize accordingly.Blog post
merge request template for your MR and ensure it is set to close the associated issue automatically.Please assign first to @rebecca. If she is OOO, assign to @skassabian. If no one is available and you cannot wait until they return, please assign to a member of the Technical Writing team. Where possible, select the technical writer who is listed for the most relevant stage group. If you need immediate assistance/review, find a technical writer who is online on Slack to request this directly. Regardless, be sure to specify any time constraints around getting the content reviewed and posted.
Continuous delivery mindset: With time-sensitive posts, don't wait to publish a post if you have enough information to go live. It's OK to publish a headline and paragraph to get the news out in a timely matter and add more details later (e.g. add more graphics, charts, etc.). We don't want to miss out on a news cycle because we're waiting for an image or supplementary information.
Inspired by error budgets used by Engineering.
Applied to the blog, error budgets incentivize forward planning and early communication of time-sensitive blog posts. This helps the Editorial team to minimize time spent on unplanned work, shuffling of the publishing schedule, or work that is subsequently wasted or does not serve our goals and objectives or the needs of our audience.
Each functional group is responsible for not exceeding an allowed budget of 15 points per quarter. The number of points given will depend on the severity of the impact to the team's workflow:
Where error budget points are incurred, a member of the Editorial team will apply the relevant label to the issue or merge request in question. Points will be totaled at the end of the quarter and communicated to functional groups who exceed their budgets, so that we can work together on solutions to prevent this in the future.
@rebecca
a heads up that your post needs to go live on a specific day.@rebecca
well ahead of time (a minimum of two working days before you expect to publish).It is not currently possible to prepare a confidential blog post without forking the www-gitlab-com project. We avoid this because forking is not straightforward for all contributors and it doesn't allow us to use review apps to preview the post before publishing. Please see below Creating MRs for confidential issues.
In exceptional circumstances, we can prepare a confidential MR in a private repository. Please leave a comment on your blog post issue to note that this is necessary, and see The Private handbook for further instructions.
We will promote anyone integrating with GitLab, even if we compete with them. It is very important to demonstrate to our customers that we do not lock them in.
If you are a partner or industry-adjacent third party who wants to write for our blog, please contact the Partner Marketing team before proceeding. GitLab team members asking on behalf of a third party should do the same.
Blog posts concerning third parties or partners, whether they are to be published on the GitLab blog or externally, should follow the standard pitching process for blog posts.
As a rule, any blog post, regardless of the author, should offer some informational, educational, or entertainment value to the reader. We do not publish material that is exclusively promotional in nature.
Please be sure to include a short bio of the guest author at the end of the post, using the format below:
### About the guest author
_Short bio describing who the author is and giving any relevant background information._
You can see a live example of a guest author bio here.
When proposing or requesting a blog post on a topic that concerns one of GitLab's business partners, it may be appropriate to seek feedback from the partner before publishing. If you are planning a blog post that discusses a partner in depth and you're not sure if it's appropriate to seek partner feedback, please ping a member of the Partner Marketing team on your issue for their input. If they think the feedback process is necessary, please follow the steps below.
1. Connect with Alliances
When brainstorming what topic to discuss and write about, loop in a partner manager from Alliances for feedback and buy-in during the 'ideation phase'. To check who the relevant partner manager is, share your blog post issue and ask in the #Alliances Slack channel or check out our partner dashboard.
At this stage you and Alliances can decide whether or not the blog post topic justifies seeking feedback from the partner in question. If so, please submit your draft blog post MR to the Editorial team for review a minimum of 5 working days before you plan to publish to ensure enough time for all parties to review.
2. Submit draft to partner for feedback
When the merge request has been reviewed by the Editorial team, please assign the blog post MR and associated issue to the partner manager to submit the draft to our partners for review while CC'ing the appropriate stakeholders from marketing for visibility. This should be done with 48 hours' courtesy notice, for the sole purpose of providing feedback on the following areas:
We should not proceed to publish the blog post until the partner manager has received the feedback and/or has received acknowledgment from the partner that they have read the draft within the 48-hour window. If we need to escalate within the Alliance team, @bjung is the highest escalation point within that team.
It should be noted that this is a courtesy review of the content, not a formal approval from our partner to publish the post. It should ultimately be GitLab's decision if to go live with the post or not.
Joint announcements with partners or other third parties should first be proposed to the Corporate Communications team ahead of writing to maximize impact and ensure alignment across teams. They will decide whether we issue a press release, blog post, or communicate via other channels. If they decide to move forward with a blog post, please follow the instructions for time-sensitive blog posts.
If we are doing a joint announcement with another company, the announcement post should appear on one party's site, to maximize impact. If both parties wish to publish a blog post about an announcement, the posts should be original and each take a unique angle, offering something new and valuable to the reader. In some cases this may mean a post takes more time to be researched, written, and reviewed, which may necessitate publishing shortly after the official announcement, if planning further ahead is not possible. Posts tend to get more traffic with this approach, rather than publishing and promoting duplicate posts on two blogs, or rushing to get a straightforward announcement out.
Official GitLab partners may use our CTA button and include promotional copy, however the blog post must still serve a function (informational or educational) other than simply promoting something.
For either type of guest post, the process and guidelines for publishing are as follows:
blog-post
and guest/partner post
.If the author of a guest post is not an official GitLab partner, they may link back to their website or own content with inline links, but may not include a CTA button or promotional copy.
We do not republish posts from other publications verbatim. The same principles apply as in Joint announcements: it's more impactful and valuable to cross-promote a story that appears on one platform than to publish the same post in two places.
Please try to include 2-3 relevant links back to about.gitlab.com, where appropriate. This is advantageous for SEO and may send some new visitors back to our site.
If there is another layer/angle to the story, we could explore this in a new post on our own blog, which could then link back to the original post on the other site. Please open an issue to propose this if that's the case.
If you spot a tweet, post, or feedback anywhere detailing an interesting use case for GitLab which you think could make a good story, open an issue and ping @kimlock to help determine whether we should pursue an interview for a blog post or case study (we will not ask the original author to create something for us).
For follow-up posts to Pick Your Brain interviews with the CEO, as soon as an interview or livestream is scheduled, please open an issue in the gitlab.com/gitlab-com/www-gitlab-com project, using the PYB blog post
template, and fill out the relevant information there.
The blog editorial team will assess the content of the post and decide how best to leverage it. This may mean publishing on the blog, on our Medium site, or something else.
Once agreed, the blog team will assign and communicate the expected publish date.
We review traffic to blog posts on a quarterly basis. You can view past analyses and takeaways in the Editorial team handbook, but below are the key points for all team members to keep in mind.
It's clear that technical/actionable/how-to content attracts the most blog readers and thus should be the focus of the majority of the content we create for the blog.
When writing a blog post, please keep the reader in mind. This person has more than likely searched for a topic or a trend and is looking for comprehensive content with a clear takeaway. Write to this person and consider the tone and the language that will best get your point across.
Our "How to get your blog post pitch accepted" section has some tips and prompts to help you prioritize our audience when planning your blog post.
It's also important to consider the context of the post. Ask yourself why it matters to the reader, and, if possible, connect your story to a broader industry issue. Don't jump in straight away with what you want to tell the reader about without first giving some thought to and communicating why the reader should be interested. That type of context can "uplevel" your content and result in a better reader experience.
There are generally two ways to go about this:
1. Include a "sweep" paragraph near the beginning of your post to contextualize
The following prompts may help you determine what to write about here:
You can see an example of "sweep" paragraphs at the beginning of this post on low-code/no-code tools, giving history and context to the topic before diving into the GitLab-specific story.
2. Uplevel the whole post
Example: "The trouble with technical interviews? They aren't like the job you're interviewing for" was originally planned to be just about how GitLab's Frontend group redesigned its technical interviews. After discussion, it was decided that there was a broader story to tell here, because the GitLab story (redesigning Frontend technical interviews) was really addressing a greater, industry-wide problem, which is that technical interviews aren't effective and aren't always inclusive.
Not every post will be suitable for this treatment, so you and the Editorial team member reviewing your post can use your discretion. In some cases it may be appropriate to tweak just the title of the post to make it broader (e.g. "How GitLab CI helps solve common DevSecOps challenges" – see below).
It is important that our blog content represents our company values of diversity, inclusion, and belonging. Not all of these points will be relevant to your blog post, but they are important values and practices to be mindful of throughout the writing process. The blog editorial team tries to check for these things, but it is better if all content is created with these values and practices in mind. Tag us if you have questions!
Our audience loves a technical post, particularly when they are "how to" focused and include screenshots, code snippets, and more.
Although normally longer blog posts don't tend to perform as well, traffic-wise, a well-thought-out technical how-to post can be long and still attract enthusiastic readers.
We conducted an audit of all event-supporting content for 2018-19 and shared the results. Below is a summary of the takeaways:
Recommendations:
What matters to our readers is what matters to GitLab. A better way to cover events that offers something new with a specific angle is to take one trend or session and do a deep dive on it, rather than trying to cover the conference as a whole.
If you want to share photos from the event such as the GitLab booth or social events, consider sharing these on personal social channels or writing a post for the Unfiltered blog.
If GitLab has been included in an analyst report and you wish to share this news, please follow the announcement request process before starting work on a blog post, as we may choose to share the news in a press release or on our social channels (for rare, big news items), for example. If it is decided that a blog post is the best way to share the news, please consider the following when drafting your blog post:
As always, please keep our (largely technical) audience in mind:
The blog post should have value for our audience beyond an announcement:
These are generally popular if GitLab genuinely has something meaningful or useful to contribute to the conversation. The point of a newsjacking post should not be self serving.
This post about an experimental Git feature is a great example, because it takes something newsy, contextualizes it, and then goes into a tutorial.
Examples of successful newsjacking posts:
Posts focusing on GitLab features or capabilities are most successful when we do the following:
Updated November 2020. Will update with complete FY21 review in February 2021.
See Blog traffic analyses for more in-depth analysis on traffic to the blog.
Qualifying story ideas:
Look for the following patterns:
Who and how to interview:
Team members can also browse the Content Marketing Dashboard to see more examples of current blog posts drawing high traffic.
Occasionally, some blog posts are better suited to publishing natively by the author on LinkedIn, or on Medium. We reach slightly different audiences on these channels, and some content will get better exposure and reach if published there. If you submit a blog post and the content team decides it's a better fit for one of these, we will let you know. For now, we will treat this segmentation as an experiment, monitor the performance of different types of content on different channels, and apply our learnings. We may then be able to start planning content for specific outlets and commission stories accordingly.
Please see the publishing process before you get started.
To publish to the blog, you will need to create a merge request for the www-gitlab-com project with a file of your blog post content formatted in Markdown. Please read through the Markdown guide for reference.
If you like, you can start by drafting your post in a Google Doc (feel free to make a copy of this blog post template). Below are instructions for formatting the content of your file correctly. If you already have your content ready to go, you can jump ahead to see how to add your blog post file with a merge request.
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. If you think one of the fields is unnecessary for your post, leave it blank and the editor who reviews your post may remove it.
---
title: "This is the post title"
author: Firstname Lastname # if name includes special characters use double quotes "First Last"
author_gitlab: GitLab.com username # ex: johndoe
author_twitter: Twitter username or gitlab # ex: johndoe
categories: news # please choose one category from list below
image_title: '/images/blogimages/post-cover-image.jpg' # optional – just remove this line if you don't want to use a cover image. See below for more info
description: "Short description for the blog post"
tags: tag1, tag2, tag3
cta_button_text: 'Watch the XXX release webcast live!' # optional
cta_button_link: 'https://page.gitlab.com/xxx.html' # optional
guest: true # required when the author is not a GitLab Team Member or there is more than one author
ee_cta: false # required only if you do not want to display the EE-trial banner
install_cta: false # required only if you do not want to display the 'Install GitLab' banner
twitter_text: "Text to tweet" # optional; If no text is provided it will use post's title.
featured: yes # reviewer should set. Please remove this line if post is Unfiltered
postType: content definition # i.e.: content marketing, product, corporate
related_posts:
- "/blog/2020/xx/xx/related-post-1/"
- "/blog/2020/xx/xx/related-post-2/"
- "/blog/2020/xx/xx/related-post-3/" # please see related posts section below for details
merch_banner: merch_one
merch_sidebar: merch_one
---
More information about each field can be found below.
The title is the headline for your post. Headlines matter, both to the reader and when it comes to search engine optimization (SEO). Below are some best practices for writing headlines:
If all this seems too much, we get it! And that's why the Editorial team will always review (and maybe tweak) your headline for SEO, style, and content. But, because you're writing a blog post as an SME (and we're not SMEs) we hope you'll put that expertise to work in the headline as much as possible.
Write out the author's name here. If you want to credit multiple authors please use the following format:
Anthony Davanzo and Kelly Hair
(see a live example of multiple authors)
Please include the guest: true
field in the frontmatter as well.
There are a few options you can choose from: pick an image from a library of original images, choose a stock image to upload yourself, request a custom cover image from Design, or publish without a cover image.
We have some original illustrations for our blog categories and most popular topics which you are welcome to choose from. You can view these in https://gitlab.com/gitlab-com/www-gitlab-com/-/tree/master/source/images/blogimages/library. In the image_title:
field in the frontmatter, please enter your chosen image's file path using the format /images/blogimages/library/engineering.png
.
Choose one from any public domain resource. Unsplash is our preferred resource for public domain images.
Please add a reference to the cover image source, owner, and license at the end of the blog post, even if it doesn't require attribution.
Please see the instructions on sizing, formatting, and storing images.
We try to keep images on the blog neutral in terms of gender, ethnicity, etc. This generally means avoiding using stock images of people. It is also better to avoid using images of people (for example, GitLab team members at an event) for the cover photo because the blog post title and description overlay the image, which can look too busy.
If you would like an original design for your blog post image, please open a design request. If you prefer, you can create an image yourself.
If the blog post is about an integration, the DRI from Partner Marketing should open a design request for a custom cover image as far in advance as possible.
If you don't have an image in mind or can't think of anything to use, just remove the image_title
field from the frontmatter. No image will appear on the blog post itself, and the default image (see below) will appear on the post's tile on the blog homepage and as the thumbnail when the post is shared on social media.
If preferred, you can use the default image as a cover image, but this is not advised as the image does not add anything to the post and takes up a lot of room beneath the blog title:
If you still want to use the default image, use the path '/images/default-blog-image.png'
in the frontmatter.
Please see the Social Marketing handbook if you would like to use a specific image for the social media thumbnail.
Add featured: yes
to the frontmatter of a post to create a featured post. The most recent featured post will be shown at the top of the blog in the featured section (even if more are tagged). To remove a post from being featured, remove the featured: yes
line from the frontmatter.
Unfiltered blog posts should not be featured.
Use only one of the following categories per post. Do not change the capitalization, spelling, or anything else, otherwise you'll create another category, which is something we don't want to do accidentally.
If you're not sure which category your post belongs in, just put a placeholder in your MR and leave a comment for your reviewer noting that.
engineering
– technical, actionable content. Anything covering how to do something, use something, or solve a problem should fall under this categoryopen source
– stories from or about our community, users, or the wider open source communityculture
– posts about remote work, working together, or GitLab cultureinsights
– industry, data, newsjacking, developer survey, etc.news
– company or product announcements (including policy changes, operational announcements, and breaking changes), news, or eventssecurity
– security-related postsunfiltered
– posts on GitLab Unfilteredreleases
- release posts, security and patch releases. Posts in the releases
category need to be in the sites/marketing/source/releases/posts
directory, not sites/marketing/source/blog/blog-posts
. Please see the Release Post handbook for more.We're working on improving category pages and tagging, but for now you can find posts under the same category by navigating to
https://about.gitlab.com/blog/categories/category-name/
. Dashes will be automatically added
to multi-word categories and all of them will be lowercased in the URL. For example, the
category "company" will be available under https://about.gitlab.com/blog/categories/company/
.
Note that there's a CI test that checks for wrong or missing categories. If one of the above should change or a new category is added, don't forget to edit the following files:
Rakefile
(search for CATEGORIES
) - responsible for the CI testsource/includes/blog/category-nav.html.haml
- responsible for the categories navbarsource/handbook/marketing/blog/index.html.md
- the handbook which you're currently readingIf a category changes, you need to replace it in all posts. Here's a one-liner command you can run:
find . sites/marketing/source/blog/blog-posts -type f -exec sed -i 's/categories: old/categories: new/' {} \;
where old
is the old category and new
is the new one.
master
and deployed. Ask a production engineer to help you.This field should provide a short summary of your blog post. It's best to think about your description in relation to the title of your post. Don't repeat the title in the description; use it as an opportunity to provide more context or information about your post for the reader, and to work in the primary keywords.
The description
meta tag is important
for SEO, and it appears underneath the title of your post on the post itself and on the blog index page. It is also part of Facebook Sharing and Twitter Cards. Descriptions should be limited to 150 characters, otherwise the text will be cut off on the index page.
The description is mandatory for all the new posts, and it has been included in the default post
frontmatter generated by the command rake new_post
.
These are included to help readers find similar posts if they are interested in a particular subject. Tags appear at the bottom of each blog post, and clicking on a tag takes you to /blog/tags where you can view all tagged posts and browse by tag.
You can include as many tags as you like, separated by commas. Please only include tags from the following list, and note that they are case sensitive. If you think a tag should exist that isn't on this list, please leave a comment for the reviewer on your MR saying which tag you'd like to use and why it should be included.
In addition to the tags above, we also have tags for GitLab Commit events. If you want your blog post to appear on the relevant post-event GitLab Commit landing page, add the relevant tag to the frontmatter in the tags
field. New tags will be added for each year of GitLab Commit.
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. Do not include any UTM parameters in the link. Always wrap their values with quotes.
The final result is a red button over the cover image of the post.
In the below example, the following was included in the blog post's frontmatter in order to generate the CTA button.
cta_button_text: 'Watch the 8.16 release webcast live!'
cta_button_link: 'https://www.youtube.com/watch?v=iYPhXm8RlxI'
Comments are present on all posts by default. In the rare case that you want to disable comments on a particular blog post, you can do so by adding a line to the frontmatter: comments: false
Please do this only with good reason, as comments are an important source of feedback and engagement on blog posts.
To not display the EE trial banner on the blog post, set ee_cta
to false
in the frontmatter. It is set to true by default, so there's no need to add ee_cta: true
to the frontmatter. Only set to false on the rare occasion you have a strong reason to not display the banner (usually in the case of posts that are for developers and our open source community).
We use these to make it faster to track the effectiveness of different types of blog posts. There are several post type categories we use to differentiate blog content:
Use the postType
frontmatter option to set the content definition.
We limit media embeds to the following providers:
We can now embed a CTA for readers to sign up for our newsletter directly from the blog post page. There are two different designs. Use the following:
<%= partial "includes/blog/content-newsletter-cta", locals: { variant: "a" } %>
Result:
OR
<%= partial "includes/blog/content-newsletter-cta", locals: { variant: "b" } %>
Result:
Note: this only works for blog post files with the extension .html.md.erb
.
Consider adding pull quotes as click-to-tweet boxes, to encourage and make it easier for readers to share key points from your blog post. This only works for blog post files with the extension .html.md.erb
.
To add a click-to-tweet box, copy the below partial and enter the text
and author
fields. If the author doesn't have a Twitter account you can use gitlab
instead.
<%= partial "includes/blog/tweet", locals: { text: '', author: '' } %>
Example:
<%= partial "includes/blog/tweet", locals: { text: 'The Operations experience then should really just be that I go to work in the morning and see an email summary of what has happened, without me having to do anything', author: 'MarkPundsack' } %>
Renders:
Ideally you should choose three blog posts related to your post, using the URL format shown. Your choices will be automatically displayed at the bottom of your blog post. Please choose posts no more than two years old and that are directly relevant to your main theme. If you do not specify related posts here, they will default to showing the three most recent posts from the same category.
These should be included by default on all blog posts. Use your discretion; if it doesn't seem appropriate to include merchandizing on a post you can leave out either the sidebar or both the sidebar and banner. Examples: If we're announcing a partnership or integration, if the blog post contains lots of images and a sidebar could distract from the content, or if the blog post is very technical in nature (a tutorial or post describing a security advisory, offensive security practices, etc) and merchandizing undermines the authenticity or intent of the content or author.
There are two steps to include these: Designate what merch sidebar and banner to add in the front matter example frontmatter above, and add the merch sidebar inside your content:
To add a merch sidebar to your blog post, you need to designate it in the front matter and include the following inside the content where you want the sidebar to appear.
<%= partial "includes/blog/blog-merch-sidebar-dynamic" %>
Merch banners are automatically added to the end of blog posts if they are designated in the frontmatter.
You can see a live example of the merchandizing in this blog post: Introducing Resource Groups.
You can also view the raw file of our example post to see how all the necessary elements have been added to the frontmatter and body of the post.
Merch items are defined in one data file and implemented across all blog posts during the build process. You can see all current merch items in blog_merch.yml
merch_one:
destination_url: "/resources/guide-to-the-cloud/"
cta_text: "Learn more"
banner_image_source: "/images/merchandising-content/mc-guide-to-app-security-ebook-vertical.png"
banner_body_title: "Guide to the Cloud"
banner_body_content: "Harness the power of the cloud with microservices, cloud-agnostic DevOps, and workflow portability."
sidebar_image_source: "/images/merchandising-content/mc-guide-to-app-security-ebook-horizontal.png"
sidebar_body_title: "Guide to the Cloud"
sidebar_body_content: "Harness the power of the cloud with microservices, cloud-agnostic DevOps, and workflow portability."
merch_two:
destination_url: "/compare/github-actions-alternative/"
cta_text: "View now"
banner_image_source: "/images/merchandising-content/mc-mastering-cicd-vertical.png"
banner_body_title: "Master your CI/CD"
banner_body_content: "Watch this webcast and learn to deliver faster with CI/CD."
sidebar_image_source: "/images/merchandising-content/mc-mastering-cicd-horizontal.png"
sidebar_body_title: "Master your CI/CD"
sidebar_body_content: "Watch the webcast"
merch_three:
destination_url: "/resources/ebook-single-app-cicd/"
cta_text: "Learn more"
banner_image_source: "/images/merchandising-content/benefits-of-single-app-cicd.jpg"
banner_body_title: "Free eBook: The benefits of single application CI/CD"
banner_body_content: "Download the ebook to learn how you can utilize CI/CD without the costly integrations or plug-in maintenance."
sidebar_image_source: "/images/merchandising-content/benefits-of-single-app-cicd.jpg"
sidebar_body_title: "Single application CI/CD"
sidebar_body_content: "How to reduce costly integrations and plug-in maintenance."
merch_four:
destination_url: "/resources/ebook-ciso-secure-software/"
cta_text: "Get the eBook"
banner_image_source: "/images/merchandising-content/mc-10-steps-every-ciso-ebook-vertical.png"
banner_body_title: "10 Steps Every CISO Should Take to Secure Next-Gen Software"
banner_body_content: "Understand three software shifts impacting security, and the steps CISOs can take to protect their business."
sidebar_image_source: "/images/merchandising-content/mc-10-steps-every-ciso-ebook-horizontal.png"
sidebar_body_title: "10 Steps to secure next-gen software"
sidebar_body_content: "Learn how DevOps will impact your security program."
- name: merch_five
destination_url: "/webcast/cloud-native-transformation/"
cta_text: "Learn more"
banner_image_source: "/images/merchandising-content/cloud-native-transformation.png"
banner_body_title: "A Cloud Native Transformation"
banner_body_content: "Learn how Ask Media Group modernized their architecture and development with microservices, containers, and Kubernetes."
-name: merch_six
destination_url: "/resources/ebook-remote-playbook/"
cta_text: "Download now"
banner_image_source: "/images/merchandising-content/remote-playbook-vertical.png"
banner_body_title: "Free eBook: The GitLab Remote Playbook"
banner_body_content: "Covering fundamentals to long-term strategy, our Remote Playbook shares how to stabilize your work-from-home team and dive deep on topics including asynchronous workflows, meetings, informal communication, and management."
sidebar_image_source: "/images/merchandising-content/remote-playbook-horizontal.png"
sidebar_body_title: "Get the Remote Playbook"
sidebar_body_content: "Empower your team to thrive remotely."
- name: merch_seven
destination_url: "/resources/ebook-version-control-best-practices/"
cta_text: "Download now"
banner_image_source: "/images/merchandising-content/version-control-collaboration-blog-merch-vertical.png"
banner_body_title: "Free eBook: Version control best practices"
banner_body_content: "Collaboration made easy: Learn how teams ship and solve problems with a single application for source code and other assets."
sidebar_image_source: "/images/merchandising-content/version-control-collaboration-blog-merch-horizontal.png"
sidebar_body_title: "Version control best practices"
sidebar_body_content: "Enhance team collaboration to accelerate delivery"
- name: merch_eight
destination_url: "https://page.gitlab.com/resources-ebook-beginner-guide-gitops.html"
cta_text: "Download now"
banner_image_source: "/images/merchandising-content/gitops-vertical-220x338.png"
banner_body_title: "Free eBook: A beginner's guide to GitOps"
banner_body_content: "GitOps takes DevOps processes and applies them to infrastructure automation. See a sample GitOps workflow and learn how to get started with GitOps."
sidebar_image_source: "/images/merchandising-content/gitops-horizontal-300x150.png"
sidebar_body_title: "A beginner's guide to GitOps"
sidebar_body_content: "Learn more about infrastructure automation."
If you have a new asset you'd like to promote with merchandise on the blog, please open an issue in the Corporate Marketing project using the blog-merch-request
issue template. When you have filled in the required copy, please ping @luke to assign someone from the Design team to create the required images. When you have these, create a merge request to add the new merch to the www-gitlab-com repository and update the current merch items in this handbook. If you're not sure how, please ping @laurenbarker or @rebecca on your issue.
Below are the two types of code blocks we commonly use on the blog. Find a number of other options in the Markdown guide.
We use this for short words or phrases included in a paragraph. For inline code, surround the word or code with single backticks (`).
Example:
This is an `in-line`
code block.
Results in:
This is an in-line
code block.
"Fenced" code blocks look like the block below. We use these for longer code snippets. To create a fenced code block, put triple backticks on one line directly above and one line directly below the code.
Example:
Results in:
this is my code block
here's another line
end
Syntax highlighting helps make code easier to read. In order to enable syntax highlighting please append the language type at the end of the code block. The name matters because every language is highlighted differently.
Example (not highlighted):
```code goes here```
document.querySelectorAll('a[href^="#"]').forEach(elem => {
elem.addEventListener('click', e => {
e.preventDefault();
let block = document.querySelector(elem.getAttribute('href')),
offset = elem.dataset.offset ? parseInt(elem.dataset.offset) : 0,
bodyOffset = document.body.getBoundingClientRect().top;
window.scrollTo({
top: block.getBoundingClientRect().top - bodyOffset + offset,
behavior: "smooth"
});
});
});
Versus (highlighted javascript):
```code goes here```javascript
(or other languages/syntaxes such as yaml, ruby, sql, etc)
document.querySelectorAll('a[href^="#"]').forEach(elem => {
elem.addEventListener('click', e => {
e.preventDefault();
let block = document.querySelector(elem.getAttribute('href')),
offset = elem.dataset.offset ? parseInt(elem.dataset.offset) : 0,
bodyOffset = document.body.getBoundingClientRect().top;
window.scrollTo({
top: block.getBoundingClientRect().top - bodyOffset + offset,
behavior: "smooth"
});
});
});
Blog images are stored in the source/images/blogimages/
directory. If your post contains many images, create a sub-directory for your post: source/images/blogimages/name-of-post/
.
Tools
, Adjust size
and adjust the entry in the Resolution
field. Preview will estimate what the resulting image size will be before you click OK
to confirm.The only images accepted for about.GitLab.com 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:
Cover image by [owner name and surname](link) on [Unsplash](link)
{: .note}
You can paste this from the box that appears on Unsplash when you have downloaded an image. For images not from Unsplash:
[Cover image](link-to-original-image) by [owner name and surname](link), licensed under [CC X](link-to-licence)
{: .note}
To add an image inline, insert the following into your markdown file, where you want the image to appear:
{: .shadow}
The alt text for your images should describe the content and function of your image for visitors using a screen reader.
There are new classes for sizing and positioning blog post images. They should be added to blog post images similar to how the shadow
class is added already:
{: .shadow.small.left.wrap-text}
The new classes are grouped into:
Size
.medium
: Display image 75 percent of page width.small
: Display image 50 percent of page widthPosition
.left
: aligned left (default).center
: centered.right
: aligned rightEffect
.wrap-text
: Only applies to images that are positioned left or right. Makes text wrap around the image.
These classes are only applied for screens 992px wide and wider.
If a Position class is used without an Effect class then there will simply be empty space where the image isn't. Similarly, using a Position class without a Size class will have little-to-no effect.
Insert the following beneath an inline image to include a caption:
This is my image caption
{: .note.text-center}
This will look as below:
This is my image caption
For technical/tutorial posts, please illustrate your examples with code blocks or screenshots. Be consistent with your examples. E.g., if you are using a generic URL
to exemplify your steps domain.com
, be consistent and keep it domain.com
, 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.
Please see the Markdown Guide for instructions for embedding videos from YouTube and other sources.
If appropriate, please add a video credit, for example:
Video directed and produced by [Aricka Flowers](/company/team/#arickaflowers)
{: .note}
Please see the Markdown guide for instructions for embedding posts from social media.
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.
Read more on Making Gifs in the Product Handbook.
If you create your own cover image, it should have 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.
Image sizes can exceed megabytes and slow down the site rendering. Follow the proportions above and learn more about resizing images.
You can go about this a couple of ways: by adding a new file to sites/marketing/source/blog/blog-posts/
in the UI, or using the terminal on your own computer.
You should have an issue for the blog post you are writing. Go to the issue and click Create merge request
.
Now you have a merge request! Please edit the title to be "Draft: Blog Post - Title of blog post".
Make sure you select the blog post template for your MR, as this contains some important tasks for you to complete.
You can assign the MR to yourself while you are working on it.
If your blog post issue is confidential, please don't create an MR using the button on your issue – instead follow the instructions below:
Closes [link to your confidential issue]
to create the connection between the issue and the MR, so that when the MR is merged the issue will close automatically.Note that your MR will not be confidential. If information is under embargo it is best to prepare the blog post in a Google Doc or locally and create the MR close to the publish time to keep the blog post private. Feel free to give a thumbs up to this feature request for confidential MRs.
Click on the link to the right of Request to merge
(this is the name of your branch).
Now navigate to sites/marketing/source/blog/blog-posts/
in the tree view, then click on the +
dropdown menu and select New file
.
Enter your filename using the format yyyy-mm-dd-name-of-your-post.html.md.erb
. This will become the URL for the blog post so please keep that in mind and don't use something like my-blog-post-draft
! 😄
Please do not include special characters, capital letters, or numbers (other than the date) in your filename as this can lead to issues with publishing and can break the link to your review app.
If you aren't sure when the post will be published, just choose an arbitrary date in the future – we will update it before publishing. If you are publishing an Unfiltered post and need to update the date yourself, please see Making changes to your blog post for instructions.
Now you can paste your post content into the window. If pasting from a Google Doc or another word processor, please make sure you convert it to plain text first. A quick way to do this is to paste everything into the URL bar of a browser, and paste it into your blog post file from there.
Note that there is no blank line at the top or lines in between your front matter items.
When ready, scroll down and enter a description of what you've just done in the Commit message
box. Make sure the Target branch
is correct (i.e. has the number and title of the issue for your blog post) then click Commit changes
.
You will then see your added file. To go back to your MR, it's easiest to go to your MRs in your dashboard (this is why it's important to assign the MR to yourself when you create it). You'll find all MRs assigned to you in the top right corner of your screen.
In your MR, if you scroll down and go to the Changes
tab, you should see the blog post file you added there.
To see a preview of your post as it will look when it's live, you will need to wait for the pipeline to pass. You can check its progress from the Pipelines
tab. When it passes, you can click on View app
near the top of your MR and it will open a new tab with your preview. Please check your review app before asking anyone else to review.
If the link to the review app results in the error shown below, please check that the filename does not have any upper case letters in it, as that can cause the link to break.
If you don't see View app
button, you may need to restart the review app.*
Click on the last pipeline icon and retry the review
job. This will re-deploy the environment and enable the review app in the MR again.
*The website and blog posts are deployed as web application into CI/CD environments. For cost savings, idle deployments can be stopped automatically, causing halted review apps.
If the blog post pipeline fails, it will suggest you retry, but the merge button will not be clickable. Instead, click on the red (failed) icon on your pipeline and you will see a list of builds with the failed ones on top. Click on the "retry" icon on the right to re-run the build.
Common errors are:
#
). Fix this by wrapping the text value into single quotes: title: 'Everyone can contribute: Insights from #GitChallenge'
---
.@
character added. This is not needed, remove the @
character.You might find the following video helpful:
If you need to make changes to your file, including editing the filename to update the date when you are ready to publish, you can edit it by going to the Changes
tab, clicking on the three dots menu on the right of your blog post file, and selecting Edit in single-file editor
, which will take you to the same interface as when you added your new file. Just make your changes, edit the commit message to say what you did and hit Commit changes
.
When you're ready, assign the MR to a fellow team member to review your post. When they have reviewed and you've addressed any comments they had and resolved any outstanding discussions, please assign your MR and the corresponding issue to @rebecca
to review.
You may find this video walkthrough helpful for creating your blog post MR from the UI:
You will need to be set up to edit the website locally in order to create your post this way. Please see GitLab 102 for instructions. If you're already set up:
git checkout master
git pull
to ensure your version of master is up to date with GitLab.comgit checkout -b new-branch-name
(substitute new-branch-name
with whatever you want to call your branch)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 filename for you. Then you just open the file, fill out the front matter and start writing, or paste your (plain text) draft in from your Google Doc.
Most blog posts require a new cover image. You should upload your chosen image to the same branch as your blog post file, so that it is all included in the same MR. This means it will be published to the website simultaneously, and also allows you to preview your cover image in the review app.
When you have selected an image to use, save it on your computer, ensuring you don't include any capital letters, spaces, or special characters in the filename.
Now go to your MR and click on the branch name afterRequest to merge
.
Navigate to source/images/blogimages/
in the tree view, then click on the +
dropdown menu and select Upload file
Drag and drop or click to upload your image file, then enter a description of what you've just done in the Commit message
box. Make sure the Target branch
is correct (i.e. has the number and title of the issue for your blog post) then click Upload file
.
To go back to your MR, it's easiest to go to your MRs in your dashboard (this is why it's important to assign the MR to yourself when you create it). You'll find all MRs assigned to you in the top right corner of your screen.
In your MR, if you scroll down and go to the Changes
tab, you should see the blog post file you added there.
Make a note of the name of your image.
Scroll down to your blog post file and click on the pencil icon (Edit file button).
This will take you to the same interface as when you added your new file. In the frontmatter, look for this field:
image_title: '/images/blogimages/post-cover-image.jpg'
Change the image filename to the name of the image you just uploaded. Ensure that you keep the whole path the same (so, starting with /images/blogimages/
). Now edit the commit message to say what you did and hit Commit changes
.
Go back to your MR. If everything has been done correctly, when the pipeline passes your review app should show the cover image as expected.
This is usually because the image filename and what you entered in the frontmatter do not correspond. Look out for typos in either the filename or in the frontmatter.
Make sure that the image path is correct (i.e. it begins with /images/blogimages/
– no missing slash at the front, no source
before the first slash).
It often helps to look at the file of another recent blog post that is already live and compare it to your file to see if there are any discrepancies.