Project

Page Builder

Create and print pages in the standard paper letter size with Svelte code. Allows for fully customizable layouts in comparison to a standard document editor.

Introduction

Page Builder is a tool used to create pages, similar to Microsoft Word, but with Svelte. This means pages can be printed as letter size pages or saved as a PDF, and can be completely customized with HTML and CSS.

The Motivation

The project idea came from creating my resume. When I would use Google Docs / Microsoft Word, I often had a hard time getting the format exactly how I wanted - for example, having multiple items separated equally and aligned properly. This however could be done pretty simply with CSS flexboxes.

Since I knew Svelte, I decided to just write my resumes in HTML and CSS, and create resuable components for sections. Now, I have full control over the look of the resume, and iterations have become faster.

Implementation

While this project post will not have a link to my current repository, I will provide the implementation details.

Creating a Page

The first step is to create a Page component. This allows creating pages in a designated size.

page.svelte
<script lang="ts">
	import type { Snippet } from 'svelte';
 
	interface Props {
		height?: string;
		width?: string;
		children?: Snippet;
	}
 
	// defaults to standard letter size
	let { height = '11in', width = '8.5in', children }: Props = $props();
</script>
 
<div class="relative bg-white p-8 text-[16px]" style="height: {height}; width: {width};">
	{@render children?.()}
</div>

Pretty simple right? Now we just wrap whatever content we in the Page Component.

example-page.svelte
<script lang="ts">
	import Page from '$lib/page.svelte';
</script>
 
<Page>
	<!-- Content goes here -->
</Page>

Printing

Just because we defined the size of the Page component, it does not mean that only that will be printed or saved as a PDF. Browsers will still try to print the entire html body - here is how we fix that.

The printing size of a page can actually be defined in the app.css using the @page css at-rule.

"The @page at-rule is a CSS at-rule used to modify different aspects of printed pages." - MDN

app.css
@page {
	size: letter;
	/* OR */
	/* size: 11in 8.5in; */
	margin: 0;
}

This should work if you only have Page components in your app - however, you may have other text on other areas in the app that you do not want printed. We can stop elements from being printed using the css @media at-rule and the print media type.

app.css
@media print {
	.noprint {
		display: none;
	}
}

You can now use the noprint class on an element to prevent it from being printed.