Home Documentation Templates Examples Showcase GitHub ↗
Theme

Core concept · Paths

Use paths that know about the project.

@pathto(...) does two useful things at once: it calculates the correct relative path from the output currently being built, and it verifies that the tracked name or concrete local path you referenced actually exists.

Prefer build errors to broken production links.

A hard-coded relative URL can be syntactically valid HTML while pointing nowhere. @pathto lets Nift catch many of those mistakes while you build.

Tracked page links

When the argument is a tracked name, Nift resolves the target output relative to the page currently being generated.

<nav>
  <a href="@pathto('/')">Home</a>
  <a href="@pathto('about')">About</a>
  <a href="@pathto('docs')">Documentation</a>
  <a href="@pathto('docs/commands')">Commands</a>
</nav>

The same header can appear at different depths

Imagine one shared header being used to build all of these outputs:

public/index.html
public/about.html
public/docs/index.html
public/docs/guides/install/index.html

A literal link such as ../../about.html can only be correct from particular locations. The same @pathto('about') expression can be reused everywhere because Nift knows which output it is currently writing.

Concrete local files

If the argument is not a tracked name, Nift can resolve an existing file path directly. This is extremely useful for project-owned frontend assets.

Stylesheets

<link
  rel="stylesheet"
  href="@pathto('public/assets/css/site.css')">

JavaScript / compiled TypeScript

<script
  type="module"
  src="@pathto('public/assets/js/app.js')"></script>

It does not matter whether app.js was authored directly or produced by TypeScript, Vite, esbuild, Rollup or another tool. The final local file exists, so Nift can reference it.

Images

<img
  src="@pathto('public/assets/images/team.jpg')"
  alt="The team">

<img
  src="@pathto('public/assets/images/logo.svg')"
  alt="Example company">

Responsive images

<picture>
  <source
    media="(min-width: 900px)"
    srcset="@pathto('public/assets/images/hero-large.webp')">
  <img
    src="@pathto('public/assets/images/hero-small.webp')"
    alt="Product interface">
</picture>

Favicons and metadata images

<link
  rel="icon"
  href="@pathto('public/favicon.svg')">

<meta
  property="og:image"
  content="@pathto('public/assets/images/social-card.png')">

Video and audio

<video
  controls
  poster="@pathto('public/assets/video/poster.jpg')">
  <source
    src="@pathto('public/assets/video/demo.mp4')"
    type="video/mp4">
</video>

Downloads

<a
  href="@pathto('public/downloads/product-guide.pdf')"
  download>
  Download the product guide
</a>

What happens when the file is missing?

Suppose the template contains:

<img
  src="@pathto('public/assets/images/product-shot.webp')"
  alt="Product screenshot">

If that path does not exist, Nift reports the unresolved target during the build. Without the project-aware check, a browser would only discover the problem after somebody requests the generated page.

Hard-coded relative paths vs project-aware paths

Hard-codedProject-aware
../../assets/css/site.css@pathto('public/assets/css/site.css')
You count directory depth manually.Nift calculates it from the current output.
A typo may survive the build.The referenced tracked/local target must resolve.
Shared partials become fragile as nesting changes.The same partial can be reused across output depths.

When ordinary URLs are still the right answer

@pathto is for targets Nift can know about: tracked outputs and local project files. External URLs remain ordinary URLs:

<a href="https://example.com">External site</a>
<script src="https://cdn.example.com/library.js"></script>
A useful rule of thumb.

If the target belongs to this repository/project, consider @pathto. If the target lives elsewhere on the web, use its normal URL.