---
title: Assembling the Site
description: Finalize and deploy your site as a static site or server-rendered app.
---

---

This guide covers advanced topics for finalizing your site, including how to handle static assets, generate secondary outputs like markdown versions of your pages or an RSS feed, add normal Jaspr routes alongside your pages, and finally build and deploy your site.

## Handling Assets

Most sites need to serve static assets like images, videos, or fonts. While you can put them in a global `web` folder, `jaspr_content` allows you to co-locate assets with your content files.

This is done using the `AssetManager`, which resolves relative paths in your content and data to the correct location in the final build, as well as hashes and optimizes assets.

To use it, you need to set up the `AssetManager` in your `main.dart`:

```dart
final assetManager = AssetManager(directory: 'content');

// ...
```

This allows you to reference images in your markdown files like `![Image](image.png)` where `image.png` is right next to your markdown file.

[Read more about Assets](/content/concepts/assets).

## Secondary Outputs

Secondary outputs allow you to generate additional files alongside your main page content. This is useful for creating things like alternative versions of your content, like a raw markdown version of a page.

`jaspr_content` comes with a few built-in secondary outputs:

- [`MarkdownOutput`](/content/concepts/secondary_outputs): Generates a `.md` file containing the raw, unparsed (but pre-processed) markdown content for each of your pages.
- [`RSSOutput`](/content/concepts/secondary_outputs): Generates an `rss.xml` feed for your site of all pages.

You can add these to your `PageConfig`:

```dart
ContentApp(
  // ...
  configResolver: PageConfig.all(
    // ...
    secondaryOutputs: [
      MarkdownOutput(),
      RSSOutput(
        title: 'My Blog Feed',
        description: 'Updates from my awesome blog.',
        siteUrl: 'https://myawesomesite.com',
      ),
    ],
  ),
)
```

#### Custom Secondary Outputs

You can also create your own secondary outputs by implementing the `SecondaryOutput` class. Read more about this in the [Secondary Outputs](/content/concepts/secondary_outputs) documentation.

## Adding Routes

While `jaspr_content` handles the routing for your content pages automatically, you might want to add other custom routes to your application, for example a landing page that is build with "normal" Jaspr.

You can achieve this by using the `ContentApp.custom` constructor and providing a `routerBuilder`. The `routerBuilder` function receives a `List<List<RouteBase>>` (one list per `RouteLoader`) and should return a `Component` that includes a `Router`.

Here's an example of how to add a custom `/` route alongside your content pages:

```dart
import 'package:jaspr/jaspr.dart';
import 'package:jaspr_content/jaspr_content.dart';
import 'package:jaspr_router/jaspr_router.dart';

class HomePage extends StatelessComponent {
  @override
  Component build(BuildContext context) {
    return h1([.text('Welcome to My Custom Site!')]);
  }
}


void main() {
  // ... Jaspr initialization

  runApp(
    ContentApp.custom(
      // ...
      routerBuilder: (List<List<RouteBase>> routes) {
        return Router(
          routes: [
            // Your custom home route.
            Route(
              path: '/',
              builder: (context, state) => HomePage(),
            ),
            // Spread the routes generated by jaspr_content.
            ...routes.expand((r) => r).toList(),
          ],
        );
      },
    ),
  );
}
```

This approach allows you to seamlessly integrate a `jaspr_content` site within a larger Jaspr application, combining generated content with custom application logic.

## Building and Deploying

You can use `jaspr_content` in either **static** or **server** mode.

- In **static** mode, your site is built as a static site. This means that all content is pre-rendered and served as static files. This is the recommended approach for most use cases, as it allows for faster load times and better SEO.

- In **server** mode, your site is rendered on the server for each request. This allows for dynamic content and is useful for sites that require real-time data or user-specific content.

---

Building and deploying your site is the same as with normal Jaspr apps. Simply use the `jaspr build` command to build your site.

Check out the general [Deploying](/dev/deploying) guide for more information on how to deploy your site after building.
