@levino/shipyard-base

The base package is the foundation of shipyard. It provides the core configuration system and layouts that power your site.

Installation

npm install @levino/shipyard-base

Peer Dependencies

npm install tailwindcss daisyui @tailwindcss/typography
PackageVersion
astro^5.7
tailwindcss^3
daisyui^4
@tailwindcss/typography^0.5.10

Tailwind Configuration

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.

Configuration

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' },
      },
    }),
  ],
})

Configuration Options

OptionTypeRequiredDefaultDescription
brandstringYesBrand name displayed in navigation bar and sidebar
titlestringYesSite title used in the HTML <title> tag
taglinestringYesShort description of your site
navigationNavigationTreeYesGlobal navigation structure (see below)
scriptsScript[]No[]Scripts to include in the page head
footerFooterConfigNoFooter configuration (links, copyright, style)
hideBrandingbooleanNofalseHide 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:

PropertyTypeRequiredDefaultDescription
labelstringNoKey nameDisplay text in navigation
hrefstringNoLink destination URL
subEntryNavigationTreeNoNested 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' },
}

Adding Scripts

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.',
  },
})
OptionTypeDefaultDescription
style'light' | 'dark''light'Footer color theme
links(FooterLink | FooterLinkColumn)[][]Footer links or columns
copyrightstringCopyright notice (supports HTML)
logoFooterLogoOptional footer logo
PropertyTypeRequiredDescription
labelstringYesDisplay text for the link
tostringOne of to/hrefInternal link path (locale prefix added automatically)
hrefstringOne of to/hrefExternal URL (opens in new tab)

FooterLinkColumn Properties

PropertyTypeRequiredDescription
titlestringYesColumn header text
itemsFooterLink[]YesLinks within this column

FooterLogo Properties

PropertyTypeRequiredDescription
altstringYesAlt text for the logo
srcstringYesLogo image source URL
srcDarkstringNoOptional dark mode logo
hrefstringNoLink URL when clicking the logo
widthnumberNoLogo width in pixels
heightnumberNoLogo height in pixels

Shipyard Branding

By default, the footer displays a “Built with Shipyard” link. To hide this branding:

shipyard({
  // ... other options
  hideBranding: true,
})

Layouts

shipyard provides layouts for your pages.

Page Layout

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>
PropTypeDescription
titlestringPage title (combined with site title)
descriptionstringPage description for SEO

Markdown Layout

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...

Splash Layout

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.

Configuration

Use the onBrokenLinks option to control what happens when broken links are detected:

ValueBehavior
'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',
})

What Gets Checked

  • Internal links starting with / (e.g., /docs/getting-started)
  • Links with query strings and hash fragments (the base path is validated)
  • Links to HTML pages, directories with index.html, and asset files

What Gets Ignored

  • External URLs (https://, http://)
  • Anchor links (#section)
  • Special protocols (mailto:, tel:, javascript:, data:)

Internationalization

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({ /* ... */ })],
})