Publish an app as a portal
Goal
Take an app you have already drawn and give it a web address of its own, so people who are not in your organisation — customers, applicants, the public — can open it without signing in to the platform at all.
Before you start
You need two things, and the portal will not save without the first:
- A Studio app. A portal publishes a drawing; it does not contain one. See Create a Studio app.
- A Custom API for anything the portal reads. A portal never reads a table directly — see What a portal can read below for why. If your portal only shows text and pictures, you can skip this.
Steps
- Open your solution and choose Portals.
- Press New.
- Give it a name. This is what you and your colleagues will call it; it is not what visitors see, because everything a visitor sees is drawn.
- Choose the app to publish from the list. Only apps in this environment appear.
- Type a web address. Just the first part —
acme-support, not the whole thing. The rest of the address belongs to your Parsware deployment, and the hint under the box shows what the finished address will be. - Choose who can open it. Anyone means the address opens straight into your app; People who sign in puts a sign-in form in front of it — see Ask visitors to sign in.
- Tick what it can read — the Custom APIs this portal is allowed to call.
- Choose what visitors act as — the security roles every visitor of this portal holds. See Which tables a portal may touch.
- Leave Published unticked while you are still working, and tick it when you want the address to start answering.
- Press Save.
What a portal can read
A portal reads through the Custom APIs you list, and through nothing else. It cannot read a table directly, and there is no setting that lets it.
This is deliberate. Drawing a screen should never turn into a way of putting a table on the public internet by accident. A Custom API is something somebody wrote on purpose: it decides what a stranger may see, in a script you can read. A table is just a table.
So if a screen on your portal needs data, the order is: define the Custom API, tick it in the portal's list, and have your screen read through it.
Naming the API in your screen
A portal screen names the contract it reads, rather than a table:
loadRecords("api:par_articles@1", "articles", { top: 20, orderBy: "par_name" })
api: says this is a Custom API; par_articles is its logical name; @1 is its version, because
two versions of one API are two different contracts. The same shape works for getRecord,
createRecord, updateRecord and deleteRecord — which of those you called decides what the
platform does, and the API's own verb has to be able to answer it. A createRecord pointed at an
API that only reads will fail when the screen runs it.
In the app list, a drawn screen reads its tables directly — that is what a signed-in person's app
does, and it is why it can page and filter. On a portal there is no such door. So a screen naming
api: opens on the portal and refuses in the Shell, saying so rather than showing an empty list.
If you want one drawing in both places, it needs two screens. That is the trade the platform made deliberately: your portal reads through a contract you wrote, and the contract decides what a stranger sees.
Your API should answer { "rows": [...], "total": 12 } for a list. If it answers something else
the screen shows an empty list rather than an error, so a portal is never broken by a mistake in one
API.
The list is a permission, not a map. Ticking an API says this portal may call it — nothing more. Your screen decides when, by naming it. An API you have not ticked is refused even if a screen asks for it, which is what stops a mistake in a drawing turning into a door.
Writing needs visitors who sign in — or a challenge. An API that answers POST, PATCH, PUT or DELETE is only callable once Who can open it is set to people who sign in, because an open portal has nobody to attribute a change to. The one way round that is the next section.
Ask whoever runs your Parsware installation whether the portal host has been granted the scope your Custom API requires. Every Custom API names one, and the portal host is what holds it on your visitors' behalf — without it, every read is refused and the page simply shows nothing.
Which tables a portal may touch
The Custom APIs you tick say which contracts a page may call. Visitors act as says which tables those contracts may then read and write — the same security roles you give your own colleagues, with the same grants.
Give a portal a role of its own that grants exactly what its APIs need — Read and Create on Cases, say — rather than a role your staff use. Every visitor of the portal holds it, signed in or not.
Choose none and the portal reaches nothing. Its lists are empty and every save says That could not be saved. That is the safe way round, and it is the first thing to check when a portal shows nothing on a page that looks right.
On a portal that signs visitors in, the role is not the end of it. If the table has a rule saying whose rows are whose — see Decide whose records a visitor sees — every visitor is narrowed to their own company's rows after the role has let them in.
The platform administrator role is never offered here. A visitor holding it would be holding the whole environment.
Letting anyone send you something
Tick Let anyone send you things — it appears only while Who can open it is Anyone — and a visitor with no account can write, as long as their browser first spends a moment on a puzzle that proves it is not a script.
This is what makes a contact form possible. Without it, a portal anyone can open may read and may not write, which means asking somebody to create an account before they can send you a message — and that is not a contact form.
There is nothing to draw and nothing for the visitor to do. No box to tick, no wobbly word to read, no pictures of traffic lights. The platform gives the browser a small piece of arithmetic; a laptop finishes it before you notice, an old phone takes a moment and says Checking that you are a person… under the button while it works. Nothing is collected about the visitor, and nothing on the page comes from another company's server.
What it stops and what it does not. It makes bulk submissions expensive: a script that could send a thousand forms an hour now pays real work for every one, so in practice it sends forty. It does not stop somebody determined who is willing to run real browsers — and no such tick anywhere stops that, whatever it is called. Treat it as a spam filter with teeth rather than as a lock.
Three things it does not change:
- What can be called. Only the Custom APIs you ticked above, exactly as before.
- What can be written. The API's own request schema still decides which fields a visitor may set. A contract that accepts a subject and a message accepts a subject and a message.
- Who anybody is. Nobody signed in, so nothing is verified. If your API stores an email address the visitor typed, that is an address somebody typed. Where that matters, ask visitors to sign in instead.
portal-contact-form in samples/solutions/ is exactly this: an open portal, one write, a file
attached to it, and a page in the site itself explaining what to look at.
Opening it
Once a portal has an address, the list shows it as a link, and Open portal in the command bar opens it in a new tab. Open the portal for editing and the same address appears under the Web address box with two small buttons beside it: one opens the portal, for when you want to look at it, and one copies the address, for when you are about to send it to somebody else. Neither shows a word — the address is long, and labels beside it would push the second button onto its own line — so hover either one and it says which it is.
The address only appears once it has been saved. While you are still typing a label, the hint under the box shows what the finished address will look like; a link built from something you have not saved yet would point at a portal that is not there.
If your installation serves no portals, there is no address to open and the hint stays where the link would be. Ask whoever runs your Parsware installation.
That sentence is never about your portal — it is the platform saying it could not answer, and your drawing, your address and the Published switch are all beside the point. It is one of two things, and both belong to whoever runs your installation: the services are down, or the portal host cannot get a credential from Parsware. A wrong address says something else entirely ("Nothing is published here"), so you can tell them apart from the page itself.
What a visitor sees
Two things about a portal page are the platform's rather than yours, and both are worth knowing before somebody asks you about them.
A portal opens dark. Your own apps in Parsware open light, because that is where you sit for a working day; a portal is where a stranger arrives from a link in a message, usually on a phone, and dark is the kinder first impression. A small light/dark button floats in the top corner of every portal page — on the right in English, on the left in Persian and Arabic — and the first time a visitor presses it, that is their choice from then on: the browser remembers it, and the dark default never argues with somebody who has already answered it.
You can still draw your own switch. setTheme("light") and setTheme("dark") are available to any
handler on a drawn screen, and a button you draw and the one in the corner act on the same setting.
The one in the corner is the floor, so that a portal is readable before anybody thinks to draw one.
And the drawing reflows. A screen is drawn at a size, but it is not shown at that size: blocks that span the page keep their gap to each margin and let the middle give, and things drawn beside each other keep their share of the width. So a portal fits the window it is opened in, at any width, and nothing leaves the page.
What reflowing cannot do is re-arrange. Two columns drawn side by side stay side by side — on a handset they are two narrow columns, not one column with the second underneath the first. If a portal matters on phones, draw a screen for a phone: that is what the three A portal on a desktop / tablet / phone samples are for.
About the address
One address answers for one portal, across the whole installation. Not one per environment — one altogether. There is a single front door in front of every environment, and it decides where a request goes by looking at the address.
That has one consequence you will meet the first time you promote a solution:
Import the same solution into Test or Production and the address it asks for is already answering for the environment you built it in. So the portal arrives with no address and switched off, and shows as Needs an address in this list.
This is not an error, and nothing has gone wrong with your solution. Your development portal and your production portal were always going to need different addresses. Open the portal in the new environment, give it the address you want there, and tick Published.
A portal can also answer at an address your own organisation owns — portal.acme.com — which you
add under Your own domains and then prove is yours. See
Use your own domain.
Turning it on and off
Published is the only tick in the maker portal whose "on" means anyone in the world who knows the address can see this. So:
- It starts off, and stays off until you turn it on.
- It cannot be turned on while the portal has no address — there would be nowhere to answer. A domain of your own counts as an address only once it is verified, for the same reason: nothing answers at an unverified one.
- Turning it off stops the address answering, immediately. The app it publishes is untouched.
Deleting a portal
Deleting a portal stops the address answering and frees that address for something else. It does not delete the app — the drawing goes on being an app your own people can open in the Shell, which is the whole reason publishing is a separate thing from drawing.