Getting started

Project structure and a quick guide

How a cmsspot site is best put together, what the content types are, how to handle a contact form and mail, and where to find SFTP access at the most used web hosts, Simply.com and one.com first.

Quick start, five steps

  1. Create an account. Sign up with your email. You log in with a link; there is no password.
  2. Find your SFTP access. Host, user, port and either a key or a password. The list of web hosts at the bottom of this page says where to look.
  3. Connect the site. Settings → Connection: add the server and point cmsspot at the folder that holds the website, not the whole server. Test connection tells you if it worked.
  4. Set up folders as tabs. Settings → Folders: Pages and Articles point at their folders, and you add a tab for any other folder. Add index.php as an extra file on Pages so the front page sits with the others.
  5. Open a page and invite the client. Edit a field, save, and check the live site. Then invite the client under Team members; they get a login link to that site only.

Five minutes for a site that already exists. For a new site, build it with the structure below first.

The recommended project structure

/                        the website root (point cmsspot here)
  index.php              the front page (added as an extra file on Pages)
  pages/                 one file per page: about.php, services.php, contact.php
  articles/              one file per article, same shape as a page
  team/                  your own content type: one file per person (becomes a tab)
  cases/                 another: one file per case (becomes a tab)
  include/
    header.php           doctype to the opening of <main>, plus the menu
    footer.php           closing of <main> to </html>
    config.php           mail settings and anything secret (excluded in cmsspot)
  css/
    style.css            one stylesheet
  uploads/               images the owner adds (cmsspot uploads here)
  img/                   images that belong to the design
  .htaccess              clean URLs and caching
  robots.txt
  sitemap.xml            cmsspot can rebuild it

None of this is required. cmsspot reads any folder layout and lets you map folders to tabs in Settings. But this layout gives the cleanest editing: every file in a folder is one item, shared parts are includes, and secrets live in one file you exclude.

Content types: pages, articles and your own

Pages

One file per page in pages/. Each sets $page_title and $page_desc at the top, includes the header, writes its content in <main> with a real h1, h2 sections and p paragraphs, and includes the footer. New pages are created from the folder's own template in cmsspot.

Articles

Same shape as a page, in articles/. The Articles tab lists them, and the client creates new ones the same way. Add a date variable and Article schema in the page if you want the structured data.

Your own content types

Anything that is a list of similar things with a page each: team members, cases, products, locations, courses. Make a folder, put one file per item in it with the same markup, and add the folder as a tab in Settings → Folders. The client sees "Team" next to "Pages" and edits each person as a page. This is cmsspot's version of custom post types: a folder is a type, a file is an item.

If the items are small and belong on one page (three services, five prices), do not make a folder. Write them as a repeated block on the page with identical markup, and the client can turn it into a group in cmsspot: add, reorder, remove.

Categories

cmsspot has no categories or tags. It edits files, and a file does not carry a taxonomy. If articles need to be grouped, the plain way is a folder per group, each as its own tab, with an overview page for each that links to the articles. For a handful of articles, a list on one page is enough. If you need real categories with archive pages and filtering, that is a sign the site wants a blog engine rather than files.

The front page

index.php usually sits in the root, not in pages/. Add it as an extra file on the Pages tab in Settings → Folders, and it appears in the list with the others.

Contact form, mail and SMTP

A contact form plugin is coming to cmsspot. Until then, build the form in the page as plain PHP; it is a short file, and it stays yours. Three rules keep it safe: validate on the server, add a honeypot field for bots, and keep the mail settings in a file outside cmsspot's reach.

Put the settings in include/config.php and add include/config.php to the excluded files when you connect the site. cmsspot will then never fetch, show or edit it, and an AI assistant cannot see it either.

<?php // include/config.php (excluded in cmsspot)
return [
    'mail_to'   => 'hello@example.com',
    'smtp_host' => 'smtp.example.com',
    'smtp_user' => 'noreply@example.com',
    'smtp_pass' => 'the password from your mail provider',
    'smtp_port' => 587,
];

The form page, in pages/contact.php. It uses PHPMailer for SMTP; download it from GitHub into include/phpmailer/. If your host's plain mail() works, you can skip PHPMailer and call mail() instead.

<?php
$page_title = 'Contact us';
$page_desc = 'Call, write or visit. We reply within one working day.';
$sent = false; $error = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $cfg = require __DIR__ . '/../include/config.php';
    $name = trim($_POST['name'] ?? '');
    $email = trim($_POST['email'] ?? '');
    $msg = trim($_POST['message'] ?? '');
    if (($_POST['website'] ?? '') !== '') {           // honeypot: bots fill it, people do not see it
        $sent = true;                                 // pretend it worked, send nothing
    } elseif ($name === '' || !filter_var($email, FILTER_VALIDATE_EMAIL) || strlen($msg) < 10) {
        $error = 'Please fill in your name, a valid email and a message.';
    } else {
        require __DIR__ . '/../include/phpmailer/PHPMailer.php';
        require __DIR__ . '/../include/phpmailer/SMTP.php';
        require __DIR__ . '/../include/phpmailer/Exception.php';
        $m = new PHPMailer\PHPMailer\PHPMailer(true);
        try {
            $m->isSMTP(); $m->Host = $cfg['smtp_host']; $m->SMTPAuth = true;
            $m->Username = $cfg['smtp_user']; $m->Password = $cfg['smtp_pass'];
            $m->SMTPSecure = 'tls'; $m->Port = $cfg['smtp_port'];
            $m->setFrom($cfg['smtp_user'], 'Website');       // from your own address, reply to the visitor
            $m->addAddress($cfg['mail_to']); $m->addReplyTo($email, $name);
            $m->Subject = 'Message from the website';
            $m->Body = "From: $name <$email>\n\n$msg";       // plain text: nothing the visitor typed can run
            $m->send(); $sent = true;
        } catch (Exception $ex) { $error = 'The message could not be sent. Please call us instead.'; }
    }
}
require __DIR__ . '/../include/header.php';
?>
<main>
    <h1>Contact us</h1>
    <p>Call <a href="tel:+4512345678">+45 12 34 56 78</a> or send a message. We reply within one working day.</p>
    <?php if ($sent): ?><p>Thank you. We have your message.</p><?php else: ?>
    <?php if ($error): ?><p class="error"><?= htmlspecialchars($error) ?></p><?php endif; ?>
    <form method="post">
        <label>Name <input name="name" required></label>
        <label>Email <input name="email" type="email" required></label>
        <label>Message <textarea name="message" required minlength="10"></textarea></label>
        <div style="position:absolute;left:-10000px" aria-hidden="true"><label>Website <input name="website" tabindex="-1" autocomplete="off"></label></div>
        <button type="submit">Send</button>
    </form>
    <?php endif; ?>
</main>
<?php require __DIR__ . '/../include/footer.php'; ?>

The texts on the page (the heading, the intro, the thank-you line) are ordinary fields in cmsspot. The PHP around them is locked, so the client cannot break the form. If a form gets spam anyway, add a simple rate limit: one message per address per minute, kept in a small file outside the web root.

Where the SMTP details come from: your mail provider. For Microsoft 365 and Google Workspace, use an app password or an SMTP relay as their documentation describes; many Danish web hosts also offer an SMTP server with the hosting package, and its address is in the welcome email.

Before you connect: a checklist

The full build guide with templates is on Build with AI, and it can be added to Claude so the site is built this way from the start.

Where to find SFTP access at the most used web hosts

cmsspot connects over SFTP (port 22 on most hosts) with a key or a password. Plain FTP is not supported, because it sends the password in the clear. Every host below offers SFTP; where we have checked the host's own guide, the link goes straight to it. For the others, the link goes to the host, and the note says what to search for in their help centre.

Web hostWhere SFTP access is
Simply.com (Denmark)SFTP runs through SSH: add your public key under Website → SSH access in the control panel, then connect to ssh.simply.com with your FTP username. Direct guide.
one.comIn the one.com control panel, open Advanced settings and click SSH & FTP to enable SFTP and see host and username. Search the help centre for "SSH" if the tile is not there.
DanDomain (Denmark)Search the support pages for "FTP" or "SFTP". Access is shown on the web hosting product in the customer centre.
Curanet (Denmark)Search the support pages for "SFTP". Curanet hosting supports SFTP on the hosting account.
Scannet (Denmark)Search the support pages for "SFTP" or "SSH".
HostingerCreate an FTP account under FTP Accounts and connect with SFTP on port 22; SSH keys under SSH Access. Direct guide.
IONOSCreate an SFTP or SFTP+SSH account under Hosting → SFTP & SSH, optionally limited to one directory. Direct guide.
STRATODatabases and Web space → SFTP & SSH, create an access with a start directory, connect on port 22. Direct guide.
SiteGroundSearch the help centre for "SFTP". SSH keys are managed in Site Tools under Devs → SSH Keys Manager.
Hetzner (Webhosting)Search the docs for "SFTP". SSH and SFTP access is enabled per web hosting account in konsoleH.
BluehostSearch the help centre for "SFTP". SSH access must be enabled on the account first.
GoDaddySearch the help centre for "SFTP". SSH is enabled under the hosting account settings.
NamecheapSearch the knowledgebase for "SFTP". Shared hosting uses a non-standard port; the article states it.
DreamHostSearch the help centre for "SFTP". Each hosting user can be set to SFTP or shell access.
InfomaniakSearch the support pages for "SFTP" or "SSH". Access is per site under the web hosting product.
OVHcloudHosting plans → your plan → FTP-SSH: enable SFTP for the FTP user, then connect with the same user. Direct guide.

Checked October 2026. Hosts move their help pages; if a link is stale, search the host's help centre for "SFTP" or "SSH". If your host is not here and offers SFTP, it works the same way.

Two things that go wrong most often

The wrong folder. Point cmsspot at the website's own folder (often public_html, www or htdocs), not the account's home folder. cmsspot warns if the folder looks like the top of a server.

FTP instead of SFTP. The welcome email from many hosts lists plain FTP on port 21. Look for SFTP or SSH on port 22; it is usually a separate setting or a separate account, as the notes above describe.

Get started

Connect your first site

Create an account, add the server, open a page. Five minutes from start to the first saved change.