The base package is the foundation of shipyard. It provides the core configuration system and layouts that power your site.
npm install @levino/shipyard-base
npm install tailwindcss daisyui @tailwindcss/typography
| Package | Version |
|---|---|
astro | ^5.7 |
tailwindcss | ^3 |
daisyui | ^4 |
@tailwindcss/typography | ^0.5.10 |
For Tailwind to correctly pick up the classes used in shipyard components, you need to add the package paths to the content array in your tailwind.config.mjs:
const path = require('node:path')
/** @type {import('tailwindcss').Config} */
export default {
content: [
'./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}',
// Add this to include shipyard-base component styles
path.join(
path.dirname(require.resolve('@levino/shipyard-base')),
'../astro/**/*.astro',
),
],
// ... rest of your config
}
This ensures that Tailwind scans the shipyard component files and includes all necessary CSS classes in your build.
Add the shipyard integration to your astro.config.mjs:
import shipyard from '@levino/shipyard-base'
import { defineConfig } from 'astro/config'
export default defineConfig({
integrations: [
shipyard({
brand: 'My Site',
title: 'My Awesome Site',
tagline: 'Built with shipyard',
navigation: {
docs: { label: 'Documentation', href: '/docs' },
blog: { label: 'Blog', href: '/blog' },
},
}),
],
})
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
brand | string | Yes | — | Brand name displayed in navigation bar and sidebar |
title | string | Yes | — | Site title used in the HTML <title> tag |
tagline | string | Yes | — | Short description of your site |
navigation | NavigationTree | Yes | — | Global navigation structure (see below) |
scripts | Script[] | No | [] | Scripts to include in the page head |
footer | FooterConfig | No | — | Footer configuration (links, copyright, style) |
hideBranding | boolean | No | false | Hide the “Built with Shipyard” branding |
onBrokenLinks | 'ignore' | 'log' | 'warn' | 'throw' | No | 'warn' | Behavior when broken internal links are detected during build |
The navigation option defines your site’s main navigation. Each entry can have:
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
label | string | No | Key name | Display text in navigation |
href | string | No | — | Link destination URL |
subEntry | NavigationTree | No | — | Nested entries for dropdown menus |
Simple navigation:
navigation: {
docs: { label: 'Docs', href: '/docs' },
blog: { label: 'Blog', href: '/blog' },
about: { label: 'About', href: '/about' },
}
Nested navigation with dropdowns:
navigation: {
docs: {
label: 'Documentation',
subEntry: {
'getting-started': { label: 'Getting Started', href: '/docs/getting-started' },
'api-reference': { label: 'API Reference', href: '/docs/api' },
},
},
blog: { label: 'Blog', href: '/blog' },
}
Add analytics or other scripts to every page:
shipyard({
// ... other options
scripts: [
'https://example.com/analytics.js',
{ src: 'https://example.com/script.js', async: true },
],
})
Customize your site’s footer with links, copyright notice, and styling. Shipyard supports both simple (single row) and multi-column footer layouts, similar to Docusaurus.
A simple footer displays links in a horizontal row:
shipyard({
// ... other options
footer: {
links: [
{ label: 'Documentation', to: '/docs' },
{ label: 'Blog', to: '/blog' },
{ label: 'GitHub', href: 'https://github.com/myorg/myrepo' },
],
copyright: 'Copyright © 2025 My Company. All rights reserved.',
},
})
For a multi-column layout, use objects with title and items:
shipyard({
// ... other options
footer: {
style: 'dark',
links: [
{
title: 'Docs',
items: [
{ label: 'Getting Started', to: '/docs' },
{ label: 'API Reference', to: '/docs/api' },
],
},
{
title: 'Community',
items: [
{ label: 'Blog', to: '/blog' },
{ label: 'GitHub', href: 'https://github.com/myorg/myrepo' },
],
},
],
copyright: 'Copyright © 2025 My Company.',
},
})
| Option | Type | Default | Description |
|---|---|---|---|
style | 'light' | 'dark' | 'light' | Footer color theme |
links | (FooterLink | FooterLinkColumn)[] | [] | Footer links or columns |
copyright | string | — | Copyright notice (supports HTML) |
logo | FooterLogo | — | Optional footer logo |
| Property | Type | Required | Description |
|---|---|---|---|
label | string | Yes | Display text for the link |
to | string | One of to/href | Internal link path (locale prefix added automatically) |
href | string | One of to/href | External URL (opens in new tab) |
| Property | Type | Required | Description |
|---|---|---|---|
title | string | Yes | Column header text |
items | FooterLink[] | Yes | Links within this column |
| Property | Type | Required | Description |
|---|---|---|---|
alt | string | Yes | Alt text for the logo |
src | string | Yes | Logo image source URL |
srcDark | string | No | Optional dark mode logo |
href | string | No | Link URL when clicking the logo |
width | number | No | Logo width in pixels |
height | number | No | Logo height in pixels |
By default, the footer displays a “Built with Shipyard” link. To hide this branding:
shipyard({
// ... other options
hideBranding: true,
})
shipyard provides layouts for your pages.
The base layout for all pages. Includes navigation bar, optional sidebar, and footer. Use this when building custom Astro components.
Usage in Astro:
---
import { Page } from '@levino/shipyard-base/layouts'
---
<Page title="My Page" description="Page description">
<h1>Page Content</h1>
</Page>
| Prop | Type | Description |
|---|---|---|
title | string | Page title (combined with site title) |
description | string | Page description for SEO |
A layout with Tailwind Typography (prose) styling. Use this for standalone markdown pages.
---
layout: '@levino/shipyard-base/layouts/Markdown.astro'
title: My Page
---
# My Page
Your markdown content with nice typography...
A layout with centered content but without prose styling. Ideal for landing pages with custom styling.
---
layout: '@levino/shipyard-base/layouts/Splash.astro'
title: Welcome
---
<div class="hero">
<h1>Welcome to My Site</h1>
</div>
Shipyard automatically checks for broken internal links during production builds. This helps you catch issues before deploying your site.
Use the onBrokenLinks option to control what happens when broken links are detected:
| Value | Behavior |
|---|---|
'ignore' | Don’t check for broken links |
'log' | Log broken links but continue build |
'warn' | Log warnings for broken links (default) |
'throw' | Fail the build on broken links |
Example - Fail build on broken links:
shipyard({
brand: 'My Site',
title: 'My Site',
tagline: 'Built with shipyard',
navigation: { /* ... */ },
onBrokenLinks: 'throw',
})
/ (e.g., /docs/getting-started)index.html, and asset fileshttps://, http://)#section)mailto:, tel:, javascript:, data:)Navigation links automatically receive locale prefixes when Astro’s i18n is configured:
export default defineConfig({
i18n: {
defaultLocale: 'en',
locales: ['en', 'de'],
routing: { prefixDefaultLocale: true },
},
integrations: [shipyard({ /* ... */ })],
})