---
title: Pages and basics
---

In Rakkas, a page is a React component default exported from a module in the `src/routes` directory with a name that matches `*.page.jsx` (or `tsx`).

Rakkas has a file system-based router. The file name determines the URL path. The rules are as you would expect:

| Module name                       | URL path      |
| --------------------------------- | ------------- |
| `src/routes/index.page.jsx`       | `/`           |
| `src/routes/about.page.jsx`       | `/about`      |
| `src/routes/about/index.page.jsx` | also `/about` |

This specific naming convention (`<name>.page.{extension}`) allows you to have your helper libraries and components next to your page components without accidentally exposing them as routes.

A very simple Rakkas page would look like this:

<CodeViewer name="guide-samples" />

## The `useHead` hook and the `Head` component

Rakkas provides a `useHead` hook for managing the the document head elements like `title`, `meta`, `link` etc.

```jsx
useHead({
  // Shorthands for common tags
  title: "...", // <title>...</title>
  description: "...", // <meta name="description" content="...">
  canonical: "...", // <link rel="canonical" href="...">

  // Open Graph shorthands
  "og:title": "...", // <meta property="og:title" content="...">
  "og:description": "...", // <meta property="og:description" content="...">
  "og:url": "...", // <meta property="og:url" content="...">
  "og:image": "...", // <meta property="og:image" content="...">

  // Twitter shorthands
  "twitter:title": "...", // <meta name="twitter:title" content="...">
  "twitter:description": "...", // <meta name="twitter:description" content="...">
  "twitter:image": "...", // <meta name="twitter:image" content="...">
  "twitter:card": "...", // <meta name="twitter:card" content="...">

  // Attributes for <html>, <head> and <body> tags
  htmlAttributes: { lang: "en" }, // <html lang="en">
  headAttributes: { id: "head" }, // <head id="head">
  bodyAttributes: { class: "dark" }, // <body class="dark">

  // Other tags
  elements: [
    // Favicon
    {
      tagName: "link",
      rel: "icon",
      href: "/favicon.ico",
    },
    // Redirect when JavaScript is disabled
    {
      tagName: "noscript",
      children: [
        {
          // tagName: "meta" is the default
          "http-equiv": "refresh",
          content: "0;url=/no-js",
        },
      ],
    },
    // Third-party scripts
    {
      tagName: "script",
      src: "https://example.com/script.js",
    },
    // Inline styles
    {
      tagName: "style",
      innerText: "h1 { color: red }",
      media: "print",
    },
  ],
});
```

There is also a `Head` component that accepts the same props as `useHead`:

```jsx
<Head title="Page title" description="Page description" />
```

To deduplicate tags, you can give them a `key`. A tag that has a key will replace the previous one with the same key. Rakkas automatically generates a key for the following tags:

| Tag                                     | Autogenerated key     |
| --------------------------------------- | --------------------- |
| `<html>`                                | `html`                |
| `<head>`                                | `head`                |
| `<body>`                                | `body`                |
| `<title>`                               | `title`               |
| `<meta charset="utf-8">`                | `charset`             |
| `<meta name="viewport" ...>`            | `viewport`            |
| `<meta name="description" ...>`         | `description`         |
| `<link rel="canonical" ...>`            | `canonical`           |
| `<meta property="og:title" ...>`        | `og:title`            |
| `<meta property="og:description" ...>`  | `og:description`      |
| `<meta property="og:url" ...>`          | `og:url`              |
| `<meta property="og:image" ...>`        | `og:image`            |
| `<meta property="og:type" ...>`         | `og:type`             |
| `<meta name="twitter:title" ...>`       | `twitter:title`       |
| `<meta name="twitter:description" ...>` | `twitter:description` |
| `<meta name="twitter:image" ...>`       | `twitter:image`       |
| `<meta name="twitter:card" ...>`        | `twitter:card`        |

Rakkas generates the following default tags:

```html
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Rakkas App</title>
    <!-- ... -->
  </head>
  <!-- ... -->
</html>
```

## Fast refresh

Rakkas supports Fast Refresh which allows you to edit your components and get immediate feedback for your changes without having to reload the page. Function components will be updated without losing their state (class components will lose their state). If you open one of the examples above and edit a file, the changes will be instantly reflected in the preview.

Fast Refresh only works on files that only export React components. Exporting any other value will fall back to a full reload. Exporting types is OK.
