Node.js 14+ is installed in the system.
If you don't have Node.js installed, or its version is smaller than 14, follow this guide to install it.
yarn
is installed in the system as a package manager.
Yarn in an alternative package manager for Node.js. It needs to be installed separately. If you already have Node.js installed, run the following command to add Yarn:
npm install --global yarn
Clone the repo and init submodules with the actual docs:
git clone git@github.com:gravitational/blog.git
cd blog
Install dependencies with:
yarn
Now run one of the following commands:
yarn dev
- will run development server for blog atlocalhost:3000/blog
that will autorefresh pages in real time when you edit markdown documents.yarn build
- will build static production version.yarn start
- will display documentation built withnpm run build
atlocalhost:3000
.
yarn test
– runs tests. Used on CI.yarn lint
– checks JS and TS files for errors and automatically fixes them.yarn lint-check
– checks JS and TS files for errors, but doesn't fix them. Checked in CI and on commit.yarn typecheck
– validates TypeScript type-related errors. Used on CI.yarn build-node
– builds configs and plugins for mdx.yarn extract-article-covers
- copy the image for the last five articles of the main page and the tag pages of the blog into a shared folder. This script will automatically run with theyarn build
oryarn dev
commands. To see new post cover in/blog
or/blog/tags
root page during development you have to restart development server (yarn dev
).yarn generate-rss
– generates rss-feed for blog.yarn generate-sitemap
- generates sitemap for blog.
-
Create a new folder in the
pages
folder. We will refer to this folder as the "article" folder; each blog post will have its own article folder. The name of this folder will be part of the URI address for this article (slug). For example, if you named the article folderssh-config
, the address of this article will begoteleport.com/blog/ssh-config/
. Good practice is to give the article folder a shortened version of the title of blog post itself. -
If you have images in your article, then create a new folder inside the article folder and name it
assets
. All images that will exist in the blog post should be placed in theassets
folder. -
In the article folder, create an
index.mdx
file. This will contain the main content of the blog post. -
At the very top of
index.mdx
addfrontmatter
, which is our blog post meta-information.Frontmatter
is delimited with---
, that is, allfrontmatter
is placed between two lines of---
.Frontmatter
is made up of variables calledfields
. They must be followed by a colon:
. The following fields are required:title
is the text that appears in the browser tab (see image below), as well as what appears as the title on the search results page. If the title of the article (articleTitle
) and the name of the tab are the same, you can specify only the title of the article.description
- a short and clear summary of the page content. It lets search engines and users know what content is waiting for them on the page. Often search engines use thedescription
as a short description (snippet) - which is visible in the search results page. Among other things,description
appears in the list of articles on the main page of the blog and on pages filtered by tag (here and below - the list of articles).articleTitle
is the title of the article (the blog post itself). AlsoarticleTitle
is displayed as the title in the list of articles.date
- is specified in the format "YYYYY-MM-DD". Subsequently, this format is transformed into the desired format for the article card in the list of articles and for the page of the article itself. It must be placed in doule quotation marks!author
- the author of the article.logo
- the logo field should have the structure below:logo: image: ./assets/passwordless@2x.png alt: Passwordless SSH
image
- a path to the image. Which will be displayed in the list of articles and under the title in the article.alt
- alternative text for screen readers or when the image cannot be displayed.tags
- subject tags which can be associated with the article. Blog posts can be filtered by tags. Each tag is written on a new line and preceded by a dash-
like so:tags: - teleport - security - engineering
layout: blogArticle
- this specifies the proper layout for blog articles and should not be changed.
-
A final
---
closes out thefrontmatter
. -
Here is a model
frontmatter
example:--- articleTitle: Low Latency Identity-aware Access Prox in Multiple Regions description: Access proxy is an important tool for securing access to infrastructure. title: Low latency access proxy | Teleport date: "2021-10-01" author: Kevin Nisbet logo: image: .assets/access-proxy-latency.png alt: access proxy latency tags: - teleport - security - engineering layout: blogArticle ---
-
You may need to import components for images, quotes, etc. These imports are specified after
frontmatter
. Just leave a line after the concluding---
and then start import statements. -
If the article contains images other than the one specified in
logo
, import an image component calledBlogImage
with the following code:import BlogImage from "components/BlogImage";
The
BlogImage
component is then used where appropriate like this:<BlogImage src="./assets/architecture-for-aws-iam-multiple-accounts.png" alt="architecture for aws iam multiple accounts" />
If you need a picture with a caption, use the component with
figure
andfigcaption
elements:<figure> <BlogImage alt="Cluster management screen" src="./assets/teleport-clusters-4.3.png"/> <figcaption> A new clusters management screen that allows users to search and manage clusters at scale. Previously this was a dropdown menu causing major UX issues </figcaption> </figure>
-
To import a quote component use:
import Quote from "components/Quote";
Use it like so where appropriate:
<Quote> Can we host the ACME Net platform inside our customers’ AWS accounts? </Quote>
-
An email subscription component should appear somewhere in the body of the article at an appropriate break:
import { EmailSubscribeViolet } from "components/EmailSubscribe";
It is used like this:
<EmailSubscribeViolet />
-
Here are what imports look like on the page:
import BlogImage from "components/BlogImage";
import { EmailSubscribeViolet } from "components/EmailSubscribe";
import (any further imports...)
-
Next comes the actual content of the blog post, written in
.md
/.mdx
format. -
Finally, don't hesitate to look at the
index.mdx
files in other article folders for complete examples. -
To learn more about basic
.md
/.mdx
syntax read these nice articles: