A starting point for developers looking to build a website with Astro, using Bookshop components in CloudCannon.
Create your own copy, and start creating your own components to use in the CloudCannon CMS. Build components with .jsx
or .astro
.
To try to cut down on setup time this starter template includes some commonly used features in CloudCannon.
This template is aimed at helping developers build sites quickly, rather than providing editors with a fully built editable site. If you are an editor looking for an already built template, have a look at CloudCannon's templates page.
See a demo version of this site.
To start using this template, go to the GitHub repository, and click Use this template
to make your own copy.
All commands are run from the root of the project, from a terminal:
Command | Action |
---|---|
npm install |
Installs dependencies |
npm run dev |
Starts local dev server at localhost:4321 |
npm run build |
Build your production site to ./dist/ |
npm run astro ... |
Run CLI commands like astro add , astro check |
npm run astro -- --help |
Get help using the Astro CLI |
- Clone the repository
- Run
npm install
- Run
npm start
Bookshop is a component development workflow for static websites.
Build custom components that non-technical editors can use in a page building experience in CloudCannon.
Bookshop is already set up on this project, so that you can start building components straight away.
To add a new component:
- Create a new folder in
src/components
using the component name as the folder name.- Note: If using .mdx snippets, as we are in this template, avoid using kebab-case naming conventions. Use snake_case or camelCase instead.
- Create two files in this folder
src/components/ExampleComponent/ExampleComponent.astro
---
interface Props {
background_color: string;
text_color: string;
}
const block = Astro.props;
---
<section style={`background-color: ${block.background_color}; color: ${block.text_color};`}>
<div class="container">
Replace me
</div>
</section>
<style>
.container {
max-width: var(--pageContainer);
margin: 0 auto;
padding-inline: var(--pagePadding);
}
</style>
src/components/ExampleComponent/ExampleComponent.bookshop.yml
# Metadata about this component, to be used in the CMS
spec:
structures:
- content_blocks
label: Example Component
description: A short description.
icon: 'cottage'
tags:
- Example
# Defines the structure of this component, as well as the default values
blueprint:
background_color: '#ffffff'
text_color: '#000000'
# Overrides any fields in the blueprint when viewing this component in the component browser
preview:
# Any extra CloudCannon inputs configuration to apply to the blueprint
_inputs:
Blog section with tags and pagination included.
Documentation, blog and other text heavy sections should replicate how the blog section is implemented in this template.
The blog pages in this template use MDX to allow for snippets. Snippets allow you to use HTML components throughout your markdown text.
A common layout, with changing markdown content is favored for these kinds of text heavy pages, rather than using Bookshop components - which are defined and managed in your markdown pages frontmatter.
These text heavy pages will be edited in CloudCannon's content editor, rather than the visual editor used for building pages with Bookshop components.
Astro <Image />
is used in the two placeholder components in this template.
An Astro <Image />
will process an image in your src/assets/images folder, and output an optimized image, like below:
<img
src="/_astro/my_image.hash.webp"
srcset="
/_astro/my_image.hash.webp 240w,
/_astro/my_image.hash.webp 540w,
/_astro/my_image.hash.webp 720w,
/_astro/my_image.hash.webp 1600w
"
sizes="
(max-width: 360px) 240px,
(max-width: 720px) 540px,
(max-width: 1600px) 720px,
1600px
"
alt="A description of my image."
width="1600"
height="900"
loading="lazy"
decoding="async" />
This template also demonstrates how to set uploads
paths on an input level, to allow for both processed and unprocessed images on one site.
On this template, by default, image inputs are opened at public/images
, meaning they are unprocessed images.
Components that use the Astro component are configured so the image source input opens at src/assets/images, which are images to be processed and optimized on build.
SEO inputs come set up and configured to allow editors to control SEO on a page-by-page, and sitewide basis.
Use Tailwind to add utility classes to your HTML, allowing you to style your components without leaving your HTML. This can be used in combination with normal CSS and SCSS styling, leaving you to add styles to your site however you want.
To remove Tailwind CSS:
- Remove the following packages from your
package.json
:
"dependencies": {
"tailwindcss": "^3.3.3",
"@astrojs/tailwind": "^5.0.0"
}
- Remove mentions of Tailwind from your
astro.config.mjs
import { defineConfig } from 'astro/config';
import tailwind from '@astrojs/tailwind';
export default defineConfig({
// ...
integrations: [tailwind()],
});
- Delete your
tailwind.config.mjs
file.
A Font Awesome Icon free icon pack is included, without having to set up your own kit in Font Awesome.
To add more icons:
- Go to the Font Awesome icon list
- Pick a free icon
- Go to
src/components/utility/icon.jsx
- Import the component from
'@fortawesome/free-solid-svg-icons'
,'@fortawesome/free-regular-svg-icons'
, or'@fortawesome/free-brands-svg-icons'
, depending on which kind of icon it is. Tip: After entering 'fa' into one of the destructured objects, you should see an autocomplete dropdown list to help you with the correct syntax. - Add another if statement following the format the other icons use.
- Add the name you just used in the conditional of the if statement to
data/icons.json
, which populates the icon dropdown list used for icons in the placeholder components.
To remove Font Awesome Icons:
- Remove the following packages from your
package.json
:
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^6.5.2",
"@fortawesome/free-brands-svg-icons": "^6.5.2",
"@fortawesome/free-regular-svg-icons": "^6.5.2",
"@fortawesome/free-solid-svg-icons": "^6.5.2",
"@fortawesome/react-fontawesome": "^0.2.0"
}
- Remove
src/components/utility/icon.jsx
- Remove any imports of the icon
import Icon from '../utility/icon';
- Remove
icons.json
- Remove any select inputs that were using the icon
icon:
type: select
options:
values: data.icons
- Remove icons from your defined data in
cloudcannon.config.yml
data_config:
icons:
path: data/icons.json
Demonstrates using data files to:
- Populate select inputs in CloudCannon. This is powerful for allowing editors to make styling changes to the page, within a set design system populated by an editable data file.
- Set sitewide values such as the overall site SEO settings.
- Control header and footer data to allow editors control over navigation.
Shows how to set up schemas in CloudCannon to allow for non-technical editors to create new pages, with preset frontmatter and content. Schemas can be define on a collection level, allowing your new blog pages to be different to your new landing pages. This allows for your text heavy blog/docs pages to be built and edited in the content editor, while your other pages can be built with Bookshop in the visual editor.
A cloudcannon.config.yml
file has been provided with some configuration that starts to show what can be done to configure the CMS.
The placeholder Bookshop components show how to configure your components to control inputs and previews in CloudCannon.
Markdown toolbar has all the options supported in the rich text editor, along with stylings to make them work. See the CloudCannon Docs for more information.
Shows how to set global CSS variables in Astro, to set commonly used values like pagePadding
, and pageContainer
.
Extra work could be done to write a node fs
script to write said values from a data file to the appropriate places in the code, which would then allow editors to control sitewide styles like page max-width and padding.
- Scheduling blog posts for a future date
- Editor links to colors data file
- Writing CSS vars (padding, page max-width, etc.) through an editable data file