The Complete Portfolio Website Guide
Somewhere on your hard drive right now is work that deserves better than a folder. This guide walks you all the way from "I have Fictura open" to a real, working online print store — your own domain, your own server, your own storefront, selling your own prints — with nothing skipped and nothing assumed.
You don't need to know servers, don't need to know code, and don't need to have done this before. Every term gets explained the first time it shows up. Budget about half an hour of hands-on time, plus some waiting around for the internet to catch up (DNS, mostly — more on that below).
Two quick things before you start, so nothing gets confused
This is not the same "Portfolio" you already know. Fictura has a built-in collection called Portfolio — the star-flagged favorites folder inside your library. This guide is about something bigger: the Portfolio Website feature, which builds and deploys an actual public website where visitors can browse your photos and buy prints. Different thing, same word. If you were looking for the collection, this isn't it.
This is not the same "S3" you may have seen elsewhere. Fictura also has an S3 setup guide for a completely different job — pulling and pushing your personal photo library to your own cloud storage. That has nothing to do with what we're covering here. This guide's S3 section, further down, is about optional storage for your public storefront's images — a separate concern with a separate setup.
Why do this at all
Most "sell your photos online" products are a rented storefront: you don't own the server, you don't own the database, and if the company changes its pricing or shuts down, your store goes with it. The Portfolio Website is the opposite. Fictura builds the site and hands you the keys, but the server, the domain, and everything on it belong to you. You can move it, back it up, or walk away from Fictura entirely and the site keeps running. That independence is the whole point, and it's why the setup asks you to bring your own small server rather than just flipping a switch.
What you'll need
- About $5–6 a month for a small cloud server. This is not a Fictura fee — you pay a hosting company directly, the same way you'd pay for electricity. A photography storefront doesn't need much power.
- A domain name, if you want one —
yourname.comor a subdomain likephoto.yourname.com. You don't have to buy one today to get started, but you'll need one before the site can go fully live with HTTPS (the little padlock icon browsers show for secure sites). - Time: 20–30 minutes of actually clicking things, plus DNS propagation, which can take anywhere from a few minutes to a few hours and mostly happens in the background while you do something else.
- Everything else — storage upgrades, taking real payments, using a print-on-demand company — is optional and can be added later. Nothing below is a one-shot decision you need to get right immediately.
Ready? Open Fictura's Website view. Everything in this guide happens there, or later in your site's own admin panel once it's live.
Step 1: Connection details
This is where you tell Fictura who you are and how to reach the server you're about to create.
- Domain — the exact address your site will live at (
yourname.comorphoto.yourname.com). Type it plainly: nohttps://, no trailing slash, just the name itself. - Business Name — shown in your site's header and footer, and used as a sensible default for your About page. You can change it any time.
- SSH key — think of this as a much stronger front-door lock than a password. It's a matched pair: a private half that never leaves your computer, and a public half that gets installed on your server so it recognizes you. Click Generate SSH Key and Fictura creates this pair for you — you don't need to understand the cryptography, just click the button.
- Admin email — used for two things: requesting your site's HTTPS certificate, and logging into your store's admin panel later.
- Admin password — the password for that same admin login. Set one now, or leave it blank and the server will generate one for you automatically when it's created (Fictura will show you where to find it if you go that route).
Each field saves itself as you type. Once Domain, Admin email, and an SSH key are all set, the next section appears.
Step 2: Get a server
A "cloud server" (sometimes called a VPS, or "virtual private server") is a computer that lives in someone else's data center, running around the clock, that you rent by the month. You don't ever touch it physically — everything happens over the internet — and for a photography storefront, the very cheapest one available is already more than enough power.
Fictura gives you two ways to set one up, and for a first server, the easier path — "New Server" — is the one to pick.
New Server (recommended for a first time): Fictura generates a block of text called a cloud-init file. You copy it and paste it into a box your hosting provider shows you while creating the server (we'll point out exactly where, provider by provider, below). The server reads that text the moment it's created and configures itself completely — installs everything it needs, and even installs your (still-empty) storefront — with no further steps from you.
Existing Linux box: if you already run a server and want to add the storefront to it, Fictura instead generates a script you run yourself over a terminal connection (SSH). This path assumes some comfort with the command line and is not the beginner path — if that's not you, use New Server instead.
Creating the server itself
Whichever host you use, you're looking for the same handful of settings everywhere:
- Image/OS: Ubuntu 24.04 LTS
- Size/plan: the smallest shared-CPU option — usually described as 1 vCPU, 1 GB of RAM, about 25 GB of disk — typically $4–6 a month
- Region: whichever is physically closest to most of your visitors
- SSH key: add the public key Fictura showed you in Step 1
- User data / cloud-init / startup script: paste the cloud-init file Fictura generated
A few well-known, beginner-friendly options:
- DigitalOcean — widely recommended for a first server; the clearest interface and the simplest billing.
- Hetzner Cloud — usually the cheapest, with strong European and US regions.
- Vultr — similar pricing and setup to DigitalOcean.
- Linode (also called Akamai Cloud Compute) — another solid, simple option.
- AWS Lightsail — worth it only if you're already comfortable in Amazon's AWS console; otherwise the others are simpler.
Any of these will work. Sign up, create a server with the settings above, paste in the cloud-init text, and within a couple of minutes you'll be handed an IP address — a string of numbers like 203.0.113.42 that uniquely identifies your new server on the internet. Copy that into Fictura's Server IP field.
Pointing your domain at it (DNS)
Your domain name and your server's IP address aren't connected automatically — you have to tell the internet's address book (DNS) to link them. Go to wherever you manage your domain's DNS (often the company you bought the domain from) and add what's called an A record:
- If your domain is the whole thing (
yourname.com), the A record goes on@or "root." - If it's a subdomain (
photo.yourname.com), the A record's name is justphoto. - Either way, the record's value is the server IP you just copied.
This change takes anywhere from a few minutes to a few hours to "propagate" — spread out across the internet's DNS servers — so this is a good moment to move on to the next steps while you wait.
HTTPS (the padlock)
HTTPS is what puts a padlock icon next to your address in a visitor's browser, and it's not optional if you plan to sell anything: browsers actively warn visitors away from sites without it, and payment providers require it. The good news is you don't have to do anything — once your DNS change above has propagated, the server automatically requests and installs a free, real security certificate on its own, no clicking required.
Step 3: Where your photos live (storage)
Every photo on your storefront has to be stored somewhere the website can serve it from. Fictura gives you two options, and the honest recommendation is: start with the default, and only think about the alternative once you actually have a reason to.
Server directory (the default — just leave this selected). Your images live directly on the same small server you just created. No extra sign-ups, no extra accounts, no monthly storage bill beyond the server itself. For the vast majority of photographers, especially when starting out, this is the right choice and there is nothing else to configure here. Skip straight to Step 4.
S3-compatible storage (optional, for later). If you outgrow the default — a large library, or wanting images to load faster worldwide — read the next section carefully before turning this on; it explains what an "S3 bucket" actually is and why the setup asks for two of them, not one.
What is an S3 bucket, exactly?
"S3" is a shorthand name (borrowed from Amazon's original storage product, Simple Storage Service) for a whole category of cloud storage services built the same way — think of it as a generic word, like "spreadsheet," rather than a single company's product. A bucket is just a storage container in one of these services, the same way a folder is a container for files on your own computer. You rent space in a bucket the way you'd rent a storage unit: you put files in, the provider keeps them safe and available, and you pay for what you use.
Why bother, when Server directory (using your own server's disk) already works? Two common reasons:
- Your server's disk is limited. The smallest, cheapest servers (the ones this guide recommends) come with a modest amount of disk space. A large, growing photo library can outgrow it; a bucket's storage is effectively unlimited and billed separately, so your server itself stays small and cheap.
- Speed for visitors far from your server. A bucket can be paired with a CDN (Content Delivery Network) — a network of servers scattered around the world that keep cached copies of your images close to wherever someone is browsing from. Without one, a visitor on the other side of the planet from your server waits longer for each photo to load.
Supported providers include DigitalOcean Spaces, Cloudflare R2, Backblaze B2, AWS S3, and MinIO — pick whichever you already use or prefer; they all work the same way from Fictura's point of view.
Why the setup asks for TWO buckets, not one
This is the part that trips people up, so it's worth slowing down for. When you turn on S3 storage, Fictura asks for a Public bucket URI and a Private bucket URI — two separate buckets, doing two very different jobs:
- Your public bucket holds the web-sized versions of your photos — exactly what a visitor sees when they browse your site: a photo resized down for a phone screen, a laptop screen, and so on. These are meant to be seen by literally anyone who visits your site, so this bucket is deliberately set up to be openly readable to the world and fronted by a CDN for speed. There's nothing sensitive in it — it's the equivalent of a printed postcard, not the original negative.
- Your private bucket holds your original, full-resolution files — the actual camera-quality images, the ones that get sent off to a print company when someone orders a physical print. These are locked down and never exposed to the public internet. Nobody browsing your site can reach them directly, and there's no public URL for them at all. When your storefront needs to hand one of these files to a print company to fulfill an order, it does so through a special, temporary, one-time link that expires after a set time — never by making the file itself public. Your original, full-quality work stays entirely under your control.
Put simply: public bucket = what people see, private bucket = what gets printed. Mixing these up — for instance, making your private bucket publicly readable "to make things easier" — would expose your unwatermarked, full-resolution originals to anyone who found the link, which defeats the entire point of having two buckets in the first place. Keep them separate, exactly as the setup asks.
A couple of settings worth knowing about while you're filling in the S3 fields:
- Endpoint — leave this blank if you're using plain AWS S3; only fill it in for the others (DigitalOcean Spaces, Cloudflare R2, Backblaze B2, MinIO), where it's your provider's specific web address for reaching their storage service.
- Force path-style URLs — tick this if you're using MinIO or Backblaze B2. It's a small technical difference in how those two providers expect file addresses to be formatted; leave it unticked for everyone else.
- Make sure your public bucket is actually set to public/readable in your provider's own dashboard, and that it allows requests (a "CORS rule") from your site's domain — your provider's bucket settings page will have this, usually under a "CORS" or "Cross-Origin" tab.
Again — none of this is required to launch. Server directory works fine for most photographers, and you can switch to S3 storage later without losing anything.
Step 4: Payment and print fulfillment keys
If you plan to actually sell prints, two more services get connected here — and this is a one-time thing, done here in Fictura only when you're building a brand-new server. Once your site is live, you'll manage both of these instead from your site's own admin panel (more on that panel shortly), not from Fictura.
Stripe handles taking payment from a customer's card securely. If you don't already have a Stripe account, sign up at stripe.com — it's free to create, and Stripe only takes a small percentage of transactions you actually complete. Stripe gives you two sets of keys: a sandbox (test) set and a live set. Use the sandbox keys at first, always — they let you place fake test purchases with fake card numbers so you can try out your entire checkout flow, end to end, before any real money or real customer is involved. Only switch to live keys once you've walked through a full test purchase yourself and you're confident everything works.
Prodigi is a real print-on-demand company — they print, package, and ship physical prints on your behalf whenever someone orders one, with no inventory or shipping hassle for you. (More on your fulfillment options, including not using Prodigi, further down — Prodigi is optional too.) If you're using Prodigi, sign up at prodigi.com and grab an API key from their dashboard. Just like Stripe, Prodigi gives you a sandbox environment to test in before switching to live.
Publishing
Once storage is configured, a Test connection button appears. Click it — Fictura checks that everything is reachable and correctly set up, and flags anything that needs attention with a clear explanation of what to fix.
Once Fictura can see your new site actually running on the server, the Publish button lights up. Click it. Fictura renders your photos, builds everything your site needs, and sends it all over to your server. A few minutes later, your storefront is live at your domain, photos and all.
One important distinction going forward: Publish only ever happens once — the very first time your content goes live. After that, every future update goes through Sync instead, which only sends what's actually changed (new photos, edited captions, removed photos) rather than starting over. You'll find Sync right below Publish in the same view once your first Publish is done.
Welcome to your Studio
Your site comes with its own admin panel, called Studio, reachable at https://yourdomain.com/studio. Log in with the admin email and password you set back in Step 1. This is where you'll spend most of your ongoing time from here on — writing pages, setting prices, and watching orders come in. Nothing in this section touches Fictura at all; it's entirely inside your own website.
Setting up your storefront's pages
Here's a sensible order to work through Studio's page editors for the first time.
Business
Your business name and details, shown across the site. You already gave Fictura a starting business name in Step 1 — this is where you can refine it and add anything else your storefront should show visitors.
Landing page
This is your home page, and it's the very first thing a visitor sees — worth spending real time on. It's built from a stack of drag-and-drop sections: a Hero (a large banner, usually with a headline over an image), a Statement (a block of text), a Photo Grid, a Collection Grid, and a Carousel (a scrolling row of images). Add, remove, reorder, and edit these freely until the page tells the story you want it to tell.
About (Artist Bio)
Don't skip this one. Your About page — your face, your name, your story — is consistently one of the most-visited pages on any photographer's site, because people who are about to spend money on a print want to know whose work they're buying. It starts out with a generic placeholder photo and placeholder bio text; replace both before you consider your site finished.
Legal pages: Terms of Service, Privacy Policy, Returns & Refunds, and FAQ
Every storefront needs a handful of legal pages, and Studio ships with four of them ready to go: Terms of Service, Privacy Policy, Returns & Refunds, and FAQ. Each one lives at its own address on your site and is editable the same way as any other page in Studio — through the same section-builder you used for your Landing page and About page.
What each page is for, in plain terms:
- Terms of Service — the ground rules for using your site and buying from you: what a customer is agreeing to when they place an order, how you handle disputes, what happens if something goes wrong.
- Privacy Policy — what personal information you collect from visitors and customers (names, addresses, payment details processed through Stripe, etc.), what you do with it, and how they can ask questions about it. Nearly every country now has some form of law requiring a business to disclose this.
- Returns & Refunds — your policy on cancellations, returns, damaged prints, and refunds. For a made-to-order physical product like a print, this is one of the very first things a cautious buyer looks for before trusting you with their money.
- FAQ — a general-purpose page for answering the questions you expect to get most often: shipping times, framing options, print quality, and anything else specific to your business.
These four pages start out filled with generic placeholder text, so your site isn't literally blank on day one — but that text is not written for your business, your country, or your situation, and it is not something you should leave in place once you're accepting real orders. One detail worth knowing: your FAQ page starts as a draft, meaning it's not visible to visitors until you explicitly publish it — safe to leave alone until you're ready. Your Terms of Service, Privacy Policy, and Returns & Refunds pages, however, are live by default, placeholder text and all, the moment your site goes live. Replacing them isn't a someday task — do it before you turn on real payments.
A plain disclaimer: Neither Fictura nor this guide is a law firm, and nothing here is legal advice. The placeholder text on these pages is a starting structure, not a finished legal document — it is not sufficient, on its own, for a real business taking real payments. Rules around returns, refunds, and customer data vary significantly from country to country and state to state. Before you accept real orders, please have a qualified attorney in your own jurisdiction write or review these pages — your Terms of Service and Returns & Refunds page especially.
Custom pages
Anything else you want — a Press page, a Workshops page, an FAQ that goes beyond the standard one, whatever fits your business — can be added here as a freeform page with its own address on your site (like yourdomain.com/page/workshops). Entirely optional, and easy to add later.
Collections and Photos
These sync in automatically from Fictura — you don't create them from inside Studio. What you can do here is add or edit the description shown on a collection's page, and adjust individual photo details (captions, alt text, and similar) after they've synced over.
Integrations
Every outside service your site talks to — payment, print fulfillment, and social sharing — is configured from this one page, grouped into a section per capability. Nothing here is set from Fictura; it's all entered directly in Studio, after your site is live, using credentials from each service's own dashboard.
Each option shows whether it's configured, whether it's in test or live mode, and has its own Save and Test connection buttons so you can verify a set of credentials works before relying on it.
Payment (Stripe)
Sign up at stripe.com if you haven't already — it's free to create an account, and Stripe only takes a small percentage of transactions you actually complete. Paste your Secret key from the Stripe dashboard. Stripe gives you two sets of keys, a sandbox (test) set and a live set — use sandbox keys at first, always, so you can place fake test purchases with fake card numbers and try out your entire checkout flow before any real money is involved. Only switch to live keys once you've walked through a full test purchase yourself.
Fulfillment (Prodigi, or Self)
If you're using Prodigi — a real print-on-demand company that prints, packages, and ships physical prints on your behalf whenever someone orders one — sign up at prodigi.com and paste the API key from their dashboard. Set Environment to sandbox for test orders, and only switch to live once you're ready to sell for real. If you'd rather print and ship everything yourself, choose Self instead — it needs no credentials at all.
Social Media (Bluesky, Meta, X)
Lets you share a photo or a collection straight from Studio, with the image, its description, and your default hashtags, to any of the networks below. Unlike Payment and Fulfillment, more than one social network can be turned on at once — flip on every network you use with its own Enabled toggle, independent of the others.
- Bluesky — enter your handle (e.g.
yourname.bsky.social) and an app password, not your regular account password. Generate one from Bluesky under Settings → Privacy and security → App passwords. Leave the PDS service URL field blank unless you're on a custom Bluesky server; it defaults tobsky.social. - Meta (Facebook, Instagram, Threads) — one Meta app backs all three. Create an app at developers.facebook.com, then from the Graph API Explorer exchange for a long-lived Page access token (this is what Facebook and Instagram both use) — it expires roughly every 60 days unless derived from a system-user token, so you'll need to refresh it periodically. You'll also need your Facebook Page ID and Instagram Business account ID. Threads uses an entirely separate token and its own API, so grab a Threads access token and Threads user ID independently — the Page token won't work there. Each of the three (Facebook, Instagram, Threads) becomes shareable as soon as its own fields are filled in; you don't need all three configured to use any one of them. Instagram requires a JPEG image and a roughly square-to-widescreen aspect ratio — a photo far outside that range won't be offered as an Instagram option when sharing.
- X — currently in beta. You'll need four values from the X developer portal, under your app's Keys and tokens: API key, API key secret, access token, and access token secret. The access token pair must have Read and write permission — regenerate it if you change that setting after the fact. Note that posting with an image requires a paid X API tier; X's free tier does not allow it.
- Sharing defaults — at the top of the Social Media section, set default hashtags appended to the end of every share (you can still edit them per-share when you actually compose one), and whether a link back to the photo or collection's page is included by default.
- Both Meta and X require your site to be reachable on the public internet — image URLs are fetched by Instagram/Facebook/Threads directly from your server, so none of the three can be tested from a site that isn't actually deployed and live.
Selling prints
This is the part that turns your storefront from a gallery into a shop. Two building blocks work together — Presets and Offerings — plus a choice of who actually does the printing.
Choosing how prints get fulfilled
Prodigi (print-on-demand) — the company you connected in Step 4. You never touch a print or a shipping label; when a customer orders, Prodigi automatically prints and ships it for you, and takes a cut for doing so. This is the lowest-effort option and the natural choice if you don't want to handle physical fulfillment yourself. As with Stripe, start in sandbox mode, place one full test order yourself, and only switch to live once you trust the whole flow.
Self / in-house fulfillment — for photographers who print (or have prints made locally) and ship them personally. There's no external account to connect for this option. Instead, when an order comes in, it lands in a queue inside Studio's Orders page marked awaiting fulfilment. You print it, mark it Printed, then once it's boxed and sent, mark it Shipped. Full control, more manual work — the right trade for photographers who want to be hands-on with their prints, or who print in mediums Prodigi doesn't offer.
Nothing stops you from offering both — some products through Prodigi, others self-fulfilled — side by side.
Presets: defining what you sell
A Preset is a product — for example, "16×20 Classic Frame" or "8×10 Fine Art Print." When you create one, you choose which fulfillment path handles it (Prodigi or self), its size and pricing, and a few other details specific to that path. Think of a Preset as your product catalog entry: it describes the thing, not which photos it applies to.
Offerings: choosing which photos are for sale
Creating a Preset doesn't put anything up for sale by itself — that's what Offerings is for. Here, you pick a collection, and every photo in it becomes a row with every one of your Presets as a column; ticking a box turns that specific photo into a purchasable print in that specific product. This is also literally what makes the "Purchase Print" button appear on a photo's public page — no offering enabled, no button shown.
Orders
Every sale shows up here. Orders that need your attention are flagged and pinned to the top — a failed Prodigi order, a self-fulfilled order still waiting to be printed, and so on. Refunds, when needed, are one click away from any order.
Going live checklist
Before you announce your storefront to the world, a quick pass through this list:
- Storage is configured the way you want (Server directory is fine — no action needed)
- Your About page has your real photo and real bio, not the placeholder
- Terms of Service, Privacy Policy, and Returns & Refunds have been reviewed by a qualified attorney for your jurisdiction and replaced with real content
- At least one Preset exists and is enabled for at least one photo in Offerings
- You've placed at least one full test purchase yourself in sandbox mode
- Stripe and Prodigi (if you're using it) are switched from sandbox to live
- Your domain resolves correctly and shows the padlock (HTTPS)
- You've clicked Publish, and your content is live
Keeping it running
- Updates — the site version is set once, by the deploy file, when the server is created. It never changes on a Publish or a Sync. When a newer site version is available, the Website view shows a Site update section — click Update site there to move the box to it. Before installing, the server dry-runs the new database migrations and refuses if one would fail against your data, leaving the live site untouched.
- Server history — the Website view shows the box's current and previous versions and its pre-publish database backups, with a Roll back button.
- Backups — a backup is a point-in-time snapshot you can restore the whole site to. The site does not back itself up; run one from the Website view before anything risky (a site update, a bulk admin edit, changing storage). A Database backup covers the store's data (admin edits, print offerings, order history); a Full backup adds every photo and print master too, which can be large.
- The health strip at the top of Fictura's Website view shows your live site's version, photo count, free disk space, and TLS renewal date once it's answering.
If you hit a snag anywhere in setup — Test Connection reporting something red, DNS not resolving, a publish that doesn't finish — Test Connection's own messages tell you exactly what to fix, row by row. That's almost always the fastest way back on track.