# Sequoia > Publish evergreen to the ATmosphere ## CLI Reference ### `auth` ```bash [Terminal] sequoia auth > Authenticate with your ATProto PDS OPTIONS: --logout - Remove credentials for a specific identity (or all if only one exists) [optional] FLAGS: --list - List all stored identities [optional] --help, -h - show help [optional] ``` ### `init` ```bash [Terminal] sequoia init > Initialize a new publisher configuration FLAGS: --help, -h - show help [optional] ``` ### `publish` ```bash [Terminal] sequoia publish > Publish content to ATProto FLAGS: --force, -f - Force publish all posts, ignoring change detection [optional] --dry-run, -n - Preview what would be published without making changes [optional] --help, -h - show help [optional] ``` ### `inject` ```bash [Terminal] sequoia inject > Inject site.standard.document link tags into built HTML files OPTIONS: --output, -o - Output directory to scan for HTML files [optional] FLAGS: --dry-run, -n - Preview what would be injected without making changes [optional] --help, -h - show help [optional] ``` ### `sync` ```bash [Terminal] sequoia sync > Sync state from ATProto to restore .sequoia-state.json FLAGS: --update-frontmatter, -u - Update frontmatter atUri fields in local markdown files [optional] --dry-run, -n - Preview what would be synced without making changes [optional] --help, -h - show help [optional] ``` ## Configuration Reference ### `sequoia.json` | Field | Type | Required | Default | Description | | ---------------- | -------- | -------- | ----------------------- | ----------------------------------------- | | `siteUrl` | `string` | Yes | - | Base URL of your website | | `contentDir` | `string` | Yes | - | Directory containing blog post files | | `publicationUri` | `string` | Yes | - | AT-URI of your publication record | | `imagesDir` | `string` | No | - | Directory containing cover images | | `publicDir` | `string` | No | `"./public"` | Static folder for `.well-known` files | | `outputDir` | `string` | No | - | Built output directory for inject command | | `pathPrefix` | `string` | No | `"/posts"` | URL path prefix for posts | | `pdsUrl` | `string` | No | `"https://bsky.social"` | PDS server URL, generated automatically | | `identity` | `string` | No | - | Which stored identity to use | | `frontmatter` | `object` | No | - | Custom frontmatter field mappings | #### Example ```json { "siteUrl": "https://myblog.com", "contentDir": "./content/posts", "publicationUri": "at://did:plc:abc123/site.standard.publication/self", "pathPrefix": "/blog" } ``` ### Post Frontmatter | Field | Type | Required | Default Mapping | Description | | ------------- | ---------- | -------- | --------------------------------------------------------------------- | ------------------------ | | `title` | `string` | Yes | `"title"` | Post title | | `description` | `string` | No | `"description"` | Post description/summary | | `publishDate` | `string` | Yes | `"publishDate"`, `"pubDate"`, `"date"`, `"createdAt"`, `"created_at"` | Publication date | | `coverImage` | `string` | No | `"ogImage"` | Cover image filename | | `tags` | `string[]` | No | `"tags"` | Post tags/categories | #### Example ```yaml --- title: My First Post description: An introduction to my blog publishDate: 2024-01-15 ogImage: cover.jpg tags: [welcome, intro] --- ``` #### Custom Frontmatter Mapping Override default field names in `sequoia.json`: ```json { "frontmatter": { "publishDate": "date", "coverImage": "thumbnail" } } ``` ## Publishing Sequoia makes it simple to publish standard.site documents to the AT Protocol. ### Basics After completing the initial [setup](/setup) for Sequoia, it's time to publish. Before you go live, try using the `--dry-run` flag to see what will be published. ```bash [Terminal] sequoia publish --dry-run ``` This will print out the posts that it has discovered, what will be published, and how many. Once everything looks good, send it! ```bash [Terminal] sequoia publish ``` ### Updates As you publish content Sequoia will store a record of content in `.sequoia-state.json`, keeping tack of the AT URIs for each post and generating content hashes for the content inside each markdown file. When you update a post and run the publish command, Sequoia will generate hashes again, see the difference, and update the existing post rather than creating a new one. If you happen to loose the state file or if you want to pull down records you already have published, you can use the `sync` command. ```bash [Terminal] seuqoia sync ``` Sync will use your ATProto handle to look through all of the `standard.site.document` records on your PDS, and pull down the records that are for the publication in the config. ## Quickstart If you have an existing blog using a static site generator (SSG) and you want to publish [Standard.site](https://standard.site) documents to the AT Protocol, you're in the right place! Sequoia is a simple CLI tool that will help get your initial publication setup, as well as publish documents as you deploy your site. Just follow these steps to get started. ::::steps #### Install Sequoia Install with your package manager of choice :::code-group ```bash [npm] npm i -g sequoia-cli ``` ```bash [pnpm] pnpm i -g sequoia-cli ``` ```bash [bun] bun i -g sequoia-cli ``` ::: Check to make sure it was installed correctly by running the `sequoia` command ```bash [Terminal] sequoia ``` #### Authorize In order for Sequoia to publish or update records on your PDS, you need to authoize it with your ATProto handle and an app password. :::tip You can create an app password [here](https://bsky.app/settings/app-passwords) ::: ```bash [Terminal] sequoia auth ``` #### Initialize After you have authorized Sequoia, the next step is to setup your blog as a publication. First make sure you are in your main repo for your blog SSG, then run the following: ```bash [Terminal] sequoia init ``` At this point you will be asked a series of questions to help setup Sequoia for your blog. Here is a brief overview and description for each step: * **Site URL** - The primary URL for your blog, e.g. `https://sequoia.pub` * **Content directory** - This is where your markdown files live when creating blog posts, e.g. `./src/content/blog` * **Cover images directory** - When creating standard.site documents, there is an optional `coverImage` that is used like an Opengraph image, a preview of what is in your blog. With this setting you can give a specific path to your image folder where these live, e.g. `./src/assets`. If you don't use one, then you can just press enter to leave it blank. * **Public/static directory** - The path for the folder where your public items go, e.g. `./public`. Generally used for opengraph images or icons, but in this case we need it to store a `.well-known` verification for your blog, [read more here](/verifying). * **Build output directory** - Where you published html css and js lives, e.g. `./dist` * **URL path prefix for posts** - The path that goes before a post slug, e.g. the prefix for `https://sequoia.pub/blog/hello` would be `/blog`. * **Configure your frontmatter field mappings** - In your markdown posts there is usually frontmatter with infomation like `title`, `description`, and `publishedDate`. Follow the prompts and enter the names for your frontmatter fields so Sequoia can use them for creating standard.site documents. * **Publication setup** - Here you can choose to `Create a new publication` which will create a `site.standard.publication` record on your PDS, or you can `Use an existing publication AT URI`. If you haven't done this before, select `Create a new publication`. * **Publication name** - The name of your blog * **Publication description** - A description for your blog * **Icon image path** - An optional path to your blog icon image, e.g. `./public/icon.png`. This can be left blank if you choose not to use it. * **Show in Discover feed?** - A yes or no to mark your publication whether or not you want it to be discovered by aggregators. Once you complete the initialization step the following will happen: * A new `site.standard.publication` record will be created on your PDS (if you chose to in the setup) * A new `sequoia.json` config file will be created in your project repo * A `.well-known/site.standard.publication` record will be saved to your public/static folder #### Publish You are now ready to publish your blog to the ATmosphere! Just run the following command to make sure the configuration has been setup correctly. ```bash [Terminal] sequoia publish --dry-run ``` This will print out the posts that it has discovered, what will be published, and how many. Once everything looks good, send it! ```bash [Terminal] sequoia publish ``` #### Verify The standard.site records are now published on your PDS, however there is one final step in order for aggregators to find your content: verification. There are two main pieces: ##### Publication Verification If you remember, Sequoia asked for your public/static directory. Once the publication was created, it stored a `.well-known/site.standard.publication` file there. This way once you build and deploy your site using your SSG, the file can be accessed with `https://sequoia.pub/.well-known/site.standard.publication` by aggregators. So you're already half way there; just build and deploy! ##### Document Verification Every document or blog post that is published needs a `` tag in the `` of your blog post HTML page. The content of that link tag needs to be the AT URI for the record we just published on your PDS. There are two ways you can handle these: * `sequoia inject` (recommended) - By running this command after publishing, and after building the site with your SSG, Sequoia will inject the link tags into your finished HTML. This way you don't have to manually edit it or mess with an SSG config to set it up. Just deploy the build folder after you have run `sequoia inject`! * Manual - After you have run `sequoia publish` the CLI will add in a new `atUri` field to every post's frontmatter. This way you can configure your SSG to read that frontmatter and include it in the build step, similar to how it might include an opengraph image in the meta tags. This approach gives you full control over the HTML files but will take a bit more skill. :::: **Congratulations! 🎉** You just published your blog to the AT Protocol with standard.site lexicons! There is certainly much more to learn about ATProto or Sequoia, but at least you got your foot in the door. Keep reading to find out what else is possible! ## Setup This guide covers the various aspects for setting up Sequoia ### Install Install with your package manager of choice :::code-group ```bash [npm] npm i -g sequoia-cli ``` ```bash [pnpm] pnpm i -g sequoia-cli ``` ```bash [bun] bun i -g sequoia-cli ``` ::: Check to make sure it was installed correctly by running the `sequoia` command ```bash [Terminal] sequoia ``` ### Authorize In order for Sequoia to publish or update records on your PDS, you need to authoize it with your ATProto handle and an app password. :::tip You can create an app password [here](https://bsky.app/settings/app-passwords) ::: ```bash [Terminal] sequoia auth ``` This will store credentials as a dotfile directory inside `$HOME/.config/sequoia`. If you happen to have more than one blog or publication, you can authorize additional accounts. During the initialize phase the CLI will ask which account you want to use. ### Initialize After you have authorized Sequoia, the next step is to setup your blog as a publication. First make sure you are in your main repo for your blog SSG, then run the following: ```bash [Terminal] sequoia init ``` At this point you will be asked a series of questions to help setup Sequoia for your blog. Here is a brief overview and description for each step: * **Site URL** - The primary URL for your blog, e.g. `https://sequoia.pub` * **Content directory** - This is where your markdown files live when creating blog posts, e.g. `./src/content/blog` * **Cover images directory** - When creating standard.site documents, there is an optional `coverImage` that is used like an Opengraph image, a preview of what is in your blog. With this setting you can give a specific path to your image folder where these live, e.g. `./src/assets`. If you don't use one, then you can just press enter to leave it blank. * **Public/static directory** - The path for the folder where your public items go, e.g. `./public`. Generally used for opengraph images or icons, but in this case we need it to store a `.well-known` verification for your blog, [read more here](/verifying). * **Build output directory** - Where you published html css and js lives, e.g. `./dist` * **URL path prefix for posts** - The path that goes before a post slug, e.g. the prefix for `https://sequoia.pub/blog/hello` would be `/blog`. * **Configure your frontmatter field mappings** - In your markdown posts there is usually frontmatter with infomation like `title`, `description`, and `publishedDate`. Follow the prompts and enter the names for your frontmatter fields so Sequoia can use them for creating standard.site documents. * **Publication setup** - Here you can choose to `Create a new publication` which will create a `site.standard.publication` record on your PDS, or you can `Use an existing publication AT URI`. If you haven't done this before, select `Create a new publication`. * **Publication name** - The name of your blog * **Publication description** - A description for your blog * **Icon image path** - An optional path to your blog icon image, e.g. `./public/icon.png`. This can be left blank if you choose not to use it. * **Show in Discover feed?** - A yes or no to mark your publication whether or not you want it to be discovered by aggregators. Once you complete the initialization step the following will happen: * A new `site.standard.publication` record will be created on your PDS (if you chose to in the setup) * A new `sequoia.json` config file will be created in your project repo * A `.well-known/site.standard.publication` record will be saved to your public/static folder ## Supported Frameworks :::note This list is actively being updated as more static site generators and frameworks are being tested and integrated. If you see something missing, [make a request](https://tangled.org/stevedylan.dev/sequoia/issues/new)! ::: | Framework | Status | | ---------- | ------ | | Astro | ✅ | | Hugo | ? | | 11ty | ? | | Next.js | ? | | Gatsby | ? | | Nuxt | ? | | SvelteKit | ? | | Remix | ? | | Jekyll | ? | | Docusaurus | ? | | VuePress | ? | | Gridsome | ? | | Scully | ? | | Elder.js | ? | | Bridgetown | ? | | Zola | ? | | Pelican | ? | | Hexo | ? | ## Verifying In order for your posts to show up on indexers, the chances are you need to make sure your publication and your documents are verified. :::tip You an learn more about Standard.site verification [here](https://standard.site/) ::: ### Publication Verification As specified by Standard.site, the `site.standard.publication` record is verified by placing the record `https://example.com/.well-known/site.standard.publication`. That record might look something like `at://did:plc:abc123/site.standard.publication/rkey`. Sequoia handles this for you automatically if you designate your public/static folder during the [setup](/setup). When the record is created, the record AT URI is saved in `.well-known/site.standard.publication` of your public folder. Once you deploy your site with this addition, the publication will be verified! ### Document Verification Every document or blog post that is published needs a `` tag in the `` of your blog post HTML page. The content of that link tag needs to be the AT URI for the record we just published on your PDS. There are two ways you can handle these: * `sequoia inject` (recommended) - By running this command after publishing, and after building the site with your SSG, Sequoia will inject the link tags into your finished HTML. This way you don't have to manually edit it or mess with an SSG config to set it up. Just deploy the build folder after you have run `sequoia inject`! * Manual - After you have run `sequoia publish` the CLI will add in a new `atUri` field to every post's frontmatter. This way you can configure your SSG to read that frontmatter and include it in the build step, similar to how it might include an opengraph image in the meta tags. This approach gives you full control over the HTML files but will take a bit more skill. ## What is Sequoia? Sequoia is a simple CLI that can be used to publish Standard.site lexicons to the AT Protocol. Yeah that's a mouthful; let's break it down. * [AT Protocol](https://atproto.com) - As the site says, "The AT Protocol is an open, decentralized network for building social applications." In reality it's a bit more than that. It's a new way to publish content to the web that puts control back in the hands of users without sacrificing distrubtion. There's a lot to unpack, but you can find a primer [here](https://stevedylan.dev/posts/atproto-starter/). * [Lexicons](https://atproto.com/guides/lexicon) - Lexicons are schemas used inside the AT Protocol. If you were to "like" a post, what would that consist of? Probably *who* liked it, *what* post was liked, and the *author* of the post. The unique property to lexicons is that anyone can publish them and have them verified under a domain. Then these lexicons can be used to build apps by pulling a users records, aggregating them using an indexer, and a whole lot more! * [Standard.site](https://standard.site) - Standard.site is a set of lexicons specailly designed for publishing content. It was started by the founders of [leaflet.pub](https://leaflet.pub), [pckt.blog](https://pckt.blog), and [offprint.app](https://offprint.app), with the mission of finding a schema that can be used for blog posts and blog sites themselves. So far it has proven to be the lexicon of choice for publishing content to ATProto with multiple tools and lexicons revolving around the standard. The goal of Sequoia is to make it easier for those with existing self-hosted blogs to publish their content to the ATmosphere, no matter what SSG or framework you might be using. As of right now the focus will be static sites, but if there is enough traction there might be a future package that can be used for SSR frameworks too. Sequoia is MIT open sourced and available on [Tangled](https://tangled.org/stevedylan.dev/sequoia) and [GitHub](https://github.com/stevedylandev/sequoia). ## Workflows :::warning Under construction :::