Your First Web Page

Five minutes: make an empty blueprint, write a web_page with a URL and the *public scope and a web_render with a template, a title and a description, save, activate the blueprint and open the URL.

You need access to a cluster (see Getting Access) and the rights to edit blueprints. You work in the Studio Code View, because that is where a web page's URL is set today.

Paste, save, activate, open

  1. Create an empty blueprint

    Open the blueprints overview in RUAL Studio and create a new blueprint. Type a name and press Next step. Studio asks What type of blueprint would you like. It has no web page type yet, and Build a UI Page seeds a state_page, the deprecated way to build a page. Close the dialog with the × in its corner. You now have an empty canvas.

  2. Switch to Code

    Use the Canvas | Code switch in the blueprint header. When your header has no such switch, your Studio does not include the code view yet.

  3. Paste the source

    Replace the text in the editor with this. The next section explains each line.

    Hello page
    blueprint "Hello page"
    
    flow page = web_page with {event: "hello", scopes: ["*public"]} {
      web_render(
        connection: page.connection,
        template: "<main><h1>{{title}}</h1><p>{{greeting}}, this page was rendered on the server.</p></main>",
        title: "Hello",
        description: "My first RUAL web page.",
        greeting: "Welcome"
      ) with {custom_pins: [{id: "greeting", state: "greeting", type: "value"}]}
    }
  4. Check

    Press Check (Cmd/Ctrl + Enter). It should say Compiles cleanly.

  5. Stage to canvas

    Press Stage to canvas (Cmd/Ctrl + S), then switch back to Canvas to see the blocks wired together.

  6. Save

    Press Save in the bottom bar, or Cmd/Ctrl + S. Saving is what publishes: from that moment visitors get the new version.

  7. Activate the blueprint

    Pages are inactive by default. The switch at the right of the top bar reads Inactive: click it. A new blueprint needs this once, and a page holds its URL only while its blueprint is active.

  8. Open the URL

    Open https://your-cluster/hello and view the page's source. Your template is there, inside a complete document.

What each line of the source says

  • event is the URL without the leading slash. hello is /hello, / is the home page, and a segment like products/:slug arrives on the block's params out-pin.
  • scopes says who may open it. *public is everyone. A page with no scopes at all is closed: it opens for developers only, and other visitors are sent to sign in.
  • web_render answers the request. Its connection comes from the page, and the flow reaches it from the page's flow output.
  • template is HTML with {{mustache}} values. A short one fits on one line. For anything longer, store the template and set this pin to {{> its-name}}. A template can also live on the block itself, in its html setting, which is used when the pin is empty.
  • title and description fill the head of the page for you, and the template can print them too.
  • greeting is a custom pin: a value of your own, listed under custom_pins. A custom pin named greeting is {{greeting}} in the template. Wire in what you need, such as a storage result. To hand over a whole object at once, wire it into the data pin: its fields become variables by name.
Building on the canvas instead? Right-click the canvas, choose Add new block, search for web page and pick new web page. Studio places a web render and a current request block with it. Drag out of the template, title and description pins to add a value block for each, and press + pin on the render block for a custom pin. The one thing the canvas cannot set yet is the URL: Studio has no URL button on this block, so add event and scopes in the code view.

The browser receives a complete document

Without a layout the page gets a plain HTML5 document around it, and the head tags are written for you from the pins:

View source on /hello
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Hello</title>
<meta name="description" content="My first RUAL web page.">
<link rel="canonical" href="https://your-cluster/hello">
<meta property="og:description" content="My first RUAL web page.">
<meta property="og:locale" content="en_US">
<meta property="og:title" content="Hello">
<meta property="og:type" content="website">
<meta property="og:url" content="https://your-cluster/hello">
<meta name="twitter:card" content="summary">
<script src="/static-chunks/rual-web-XXXXXXXXXX.js" nonce="..." defer></script>
<script type="speculationrules" nonce="...">...</script>
</head>
<body>
<main><h1>Hello</h1><p>Welcome, this page was rendered on the server.</p></main>
</body>
</html>

Start the template with <!doctype html> to write the whole document yourself, or name a layout. The head tags are written for you in every case.

When it does not work

You seeWhyDo this
A login page, or a redirect to /loginThe page has no *public scope, or no active page holds this URL yet.Check scopes and event, and check that the switch reads Active.
A not found page while you are signed inNo active page holds this URL.Did you save, and does the switch read Active? A page of an inactive blueprint holds no URL.
you do not have access to this pageYou are signed in, without a scope the page asks for.Add the scope to your user, or to the page.
this page's flow does not reach a web render blockThe flow ended without a web_render, a web_redirect or an httpconnection answer.Connect the flow output of the page to the render block.
This page could not be renderedThe template does not compile, or there is no template.Open the page signed in as a blueprint developer: the reason is shown to you, and only to you.
A value stays emptyThe name in {{...}} does not match a custom pin or a field of data.A missing value prints nothing and is not an error. Compare the names.

Next steps

Tutorial: A Small Webshop Storages, lists, a product page, live search, a cart and a checkout. Template Syntax Conditions, loops, filters and the variables a template sees. Actions Make a button change one row without reloading the page.

Frequently asked

How do I make a public web page in RUAL?

Add a web_page block and set its event field to the URL without the leading slash, for example shop. Give it the scope *public, connect its flow to a web_render block, write the template there, and activate the blueprint.

Why does my RUAL web page answer a 500?

A page flow that ends without an answer is a 500 that says so. Check that the flow reaches web_render, or answers another way through an httpconnection block or web_redirect, and read the message if you are signed in as a blueprint developer: visitors only see that it failed.