Back to blog
/
9 min read

Getting started

This guide will walk you through the basic configuration and customization of your trueblog installation.

Basic Site Configuration

The primary configuration is handled through the src/consts.ts file. This file contains essential settings that define your blog’s identity and behavior.

Core Configuration

src/consts.ts
export const SITE: Site = {
TITLE: 'Name of your blog',
DESCRIPTION: 'Description for your blog',
AUTHOR: 'Name of the author',
CANONICAL_URL: import.meta.env.DEV
? 'http://localhost:4321'
: 'https://example.com',
LOCALE: 'en',
CATEGORIES: ['blog', 'projects'],
OG_IMAGE: '/og-image.webp',
TWITTER: {
CREATOR: '@',
CARD: 'summary_large_image',
},
NUM_POSTS_ON_HOMEPAGE: 3,
NUM_PROJECTS_ON_HOMEPAGE: 3,
SCHEDULED_POST_MARGIN: minutesToMilliseconds(15),
};

Configuration Fields Reference

FieldRequiredDescription
TITLEYour blog’s title - appears in header, SEO, and RSS feeds
DESCRIPTIONBrief blog description for SEO and meta tags
AUTHORSite author’s name
CANONICAL_URLYour site’s base URL (automatically switches for development)
LOCALESite language code (defaults to ‘en’)
CATEGORIESContent categories for organization
OG_IMAGEDefault social media preview image path
TWITTER.CREATORTwitter handle for attribution
TWITTER.CARDTwitter card type (summary_large_image recommended)
NUM_POSTS_ON_HOMEPAGENumber of posts to show on homepage
NUM_PROJECTS_ON_HOMEPAGENumber of projects to display on homepage
SCHEDULED_POST_MARGINBuffer time for scheduled posts (in milliseconds)

Social Media Configuration

Configure your social media links in the same src/consts.ts file:

src/consts.ts
export const SOCIALS: Socials = [
{
NAME: 'Facebook',
ICON: 'facebook',
LABEL: `${SITE.AUTHOR} on Facebook`,
HREF: 'https://www.facebook.com/johndoe',
},
// Add more social media platforms here
];

Social Media Fields Reference

FieldRequiredDescription
NAMEPlatform name
ICONPlatform icon identifier
LABELAccessibility label and tooltip
HREFProfile URL

Open Graph Image Configuration

trueblog generates Open Graph images automatically at build time using Satori and Sharp. You can customize these images for both posts and your site.

Template Customization

The OG image templates are located in src/utils/og-images/templates/:

  • postTemplate.ts - For individual post images
  • siteTemplate.ts - For site-wide default images

Example template modification:

src/utils/og-images/templates/postTemplate.ts
const markup = html(`
// Your custom HTML template here
`);

Image Configuration

Customize image generation settings in src/utils/og-images/config.ts:

src/utils/og-images/config.ts
import { readFileSync } from 'fs';
import type { ImageConfig, SvgConfig } from './types';
import type { Font } from 'satori';
// Custom font configuration
const interRegular = readFileSync(
`${process.cwd()}/public/og-fonts/inter-v18-latin-regular.ttf`
);
const interBlack = readFileSync(
`${process.cwd()}/public/og-fonts/inter-v18-latin-900.ttf`
);
// Image format configuration
export const DEFAULT_IMAGE: ImageConfig = {
format: 'webp',
webpOptions: {
quality: 90,
},
};
// SVG dimensions
export const DEFAULT_SVG: SvgConfig = {
width: 1200,
height: 630,
embedFont: true,
};
// Font configuration
export const DEFAULT_FONTS: Font[] = [
{
name: 'Inter',
data: interRegular,
weight: 400,
style: 'normal',
},
{
name: 'Inter',
data: interBlack,
weight: 900,
style: 'normal',
},
];

Configuration Options Reference

Font Configuration:

OptionDescription
nameFont family name
dataFont file data
weightFont weight (400=regular, 900=bold)
styleFont style (‘normal’/‘italic’)

Image Format Options:

FormatAvailable Options
JPEGquality (1-100), chromaSubsampling, progressive, mozjpeg
WebPquality (1-100), lossless, smartSubsample, effort (0-6)
AVIFquality (1-100), lossless, chromaSubsampling, effort (0-9)

SVG Configuration:

OptionDescription
widthImage width (default: 1200px)
heightImage height (default: 630px)
embedFontWhether to embed fonts

Content Security Policy (CSP) Configuration

trueblog comes with pre-configured security headers optimized for Cloudflare Pages

Default Security Headers

The main security headers are defined in public/_headers:

public/_headers
/*
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Referrer-Policy: no-referrer
Permissions-Policy: accelerometer=(), autoplay=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(self), fullscreen=(self), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(self), xr-spatial-tracking=()
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Access-Control-Allow-Origin: https://example.com

Note: Make sure to change https://example.com in Access-Control-Allow-Origin: https://example.com to your domain. Alternatively, you can remove this line entirely if you don’t need to specify CORS access control.

Automatic CSP Hash Generation

trueblog uses Astro Shield to automatically generate Content Security Policy hashes during the build process. The system works as follows:

  1. During build, astro-shield generates hashes in src/generated/sriHashes.mjs
  2. The postbuild script (scripts/generate-csp-header.mjs) automatically adds these hashes to the _headers file

Here’s the script that handles the CSP header generation:

scripts/generate-csp-header.mjs
import fs from 'fs/promises';
import path from 'path';
import {
inlineScriptHashes,
inlineStyleHashes,
} from '../src/generated/sriHashes.mjs';
const headersPath = path.join(process.cwd(), 'dist', '_headers');
async function generateCSPHeader() {
try {
// Combine all script hashes
const scriptHashes = new Set([...inlineScriptHashes]);
// Combine all style hashes
const styleHashes = new Set([...inlineStyleHashes]);
// Generate CSP header
const cspHeader =
`Content-Security-Policy: default-src 'self'; object-src 'self'; script-src 'self' ${Array.from(
scriptHashes
)
.map(hash => `'${hash}'`)
.join(' ')}; connect-src 'self'; style-src 'self' ${Array.from(
styleHashes
)
.map(hash => `'${hash}'`)
.join(
' '
)}; base-uri 'self'; img-src 'self' https://example.com; frame-ancestors 'none'; worker-src 'self'; manifest-src 'none'; form-action 'self';`.trim();
// Read existing _headers file
let headersContent = await fs.readFile(headersPath, 'utf-8');
headersContent += '\n ' + cspHeader;
// Write updated content back to _headers file
await fs.writeFile(headersPath, headersContent);
console.log('CSP header generated and _headers file updated successfully.');
} catch (error) {
console.error('Error generating CSP header:', error);
}
}
generateCSPHeader();

In the CSP header, you will find the directive:

scripts/generate-csp-header.mjs
img-src 'self' https://example.com;

This means images are allowed from the current origin (‘self’) and https://example.com. If you load images from a different source, replace https://example.com with your own image domain. If you only use local images, you can remove https://example.com entirely to enforce stricter security.

Same goes for fonts:

If you are using custom fonts, you need to ensure that they are included in your CSP. By default, you can import fonts into the public/fonts folder and reference them locally. However, if you are loading fonts from an external provider (e.g., Google Fonts), you need to update your CSP like this:

scripts/generate-csp-header.mjs
font-src 'self' https://example.com;

Replace https://example.com with the actual URL of your font provider. This ensures that only the specified sources can load fonts, improving security while allowing external font usage.

Syntax Highlighting

For syntax highlighting, Expressive Code is used.
Its configuration is defined in ec.config.mjs.

ec.config.mjs
import { defineEcConfig } from 'astro-expressive-code';
import { pluginLineNumbers } from '@expressive-code/plugin-line-numbers';
export default defineEcConfig({
plugins: [pluginLineNumbers()],
themes: ['andromeeda'],
styleOverrides: {
// You can also override styles
borderRadius: '0.5rem',
uiFontFamily: 'JetBrains Mono',
codeFontFamily: 'JetBrains Mono',
codeFontSize: '1rem',
},
});

Post Metadata Reference

Basic Fields

You can find frontmatter structure in src/content.config.ts

FieldRequiredTypeExample / DefaultDescription
titlestring”My Blog Post”1-100 characters
pubDatetimedate (z.coerce.date())“2025-03-04T16:06:19Z”
1709571979000
”March 4, 2025”
Can accept ISO 8601, timestamps, or natural date formats
descriptionstring”Description of my post”1-320 characters
draftbooleanfalseIf true, post won’t be published
authorstring”truedaniyyel”Defaults to SITE.AUTHOR
modDatetimedate (z.coerce.date())“2025-03-04T16:06:19Z”Optional modification date
imageimage / string”./images/post.png”Min size 1200×630px if provided
demoUrlstring (URL)https://demo.example.comMust be a valid URL
repoUrlstring (URL)https://github.com/user/repoMust be a valid URL
canonicalURLstring (URL)https://blog.example.com/postMust be a valid URL
editPostobjectSee belowPost editing configuration

editPost Object Properties

PropertyRequiredTypeExample / DefaultDescription
disabledbooleanfalseDisable the edit button
urlstringhttps://github.com/user/repo/edit/mainEdit URL
textstring”Edit this post”Edit button text
appendFilePathbooleantrueAppend file path to edit URL

Quick Copy Template

---
title: ''
pubDatetime: 2025-03-04
description: ''
draft: false
author: 'truedaniyyel'
# modDatetime: 2025-03-04
# image: "./images/post.png"
# demoUrl: ""
# repoUrl: ""
# canonicalURL: ""
# editPost:
# url: ""
# text: "Edit this post"
# appendFilePath: true
---

Next Steps

After configuring these basic settings, you can:

  1. Start creating content in the src/content/ directory
  2. Customize your site’s appearance
  3. Add or modify components in src/components/
  4. Deploy your site using your preferred hosting platform

Deployment Options

Cloudflare

Configuration works out of the box with Cloudflare.

Other Hosting Platforms

For other hosting platforms, minor adjustments with CSP and SRI may be needed:

The security features work seamlessly with various Astro configurations, including Astro + Svelte or other frameworks.