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 nameURL path
src/routes/index.page.jsx/
src/routes/about.page.jsx/about
src/routes/about/index.page.jsxalso /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:

The useHead hook and the Head component

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

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:

<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:

TagAutogenerated 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 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.