<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="https://desktop.cecil.app/xsl/atom.xsl" media="all"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <id>https://desktop.cecil.app/docs/publishing/</id>
  <title>Cecil Desktop - Publishing</title>
  <subtitle><![CDATA[Manage, build, preview and publish your Cecil static sites from a native desktop app, without the terminal.]]></subtitle>
  <link href="https://desktop.cecil.app/docs/publishing/atom.xml" rel="self" type="application/atom+xml" />
  <link href="https://desktop.cecil.app/docs/publishing/" rel="alternate" type="text/html" />
  <updated>2026-11-09T10:54:07+00:00</updated>
  <author>
    <name>Cecil</name>
    <uri>https://cecil.app</uri>
  </author>
  <entry xml:lang="en">
    <id>https://desktop.cecil.app/docs/publishing/netlify/</id>
    <title>Netlify</title>
    <published>2026-11-09T10:53:41+00:00</published>
    <link href="https://desktop.cecil.app/docs/publishing/netlify/" rel="alternate" type="text/html" />
    <content type="html">
      <![CDATA[<h1>Netlify</h1>
<h2 id="token">Token<a class="heading-anchor" href="#token" aria-hidden="true" tabindex="-1"></a></h2>
<p>Netlify uses a <strong>personal access token</strong>: in Netlify, open <strong>User settings › Applications › Personal access tokens</strong> (the <strong>Create a token</strong> link of the form opens this page), and create a new token.</p>
<p>The account is shown with the email of your Netlify user.</p>
<h2 id="target-settings">Target settings<a class="heading-anchor" href="#target-settings" aria-hidden="true" tabindex="-1"></a></h2>
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Site</strong></td>
<td>The name or ID of a site of your account.</td>
</tr>
</tbody>
</table>
<p>If no site of your account has this name, a new site is created with it at the first publication, at <code translate="no">https://&lt;name&gt;.netlify.app/</code>. The name must be unique across all of Netlify: if it is already taken, choose another one.</p>
<h2 id="publication">Publication<a class="heading-anchor" href="#publication" aria-hidden="true" tabindex="-1"></a></h2>
<p>Netlify tells which files it doesn't have yet: only those are sent. Cecil Desktop then waits for Netlify to process the deployment (up to 5 minutes), and shows the URL of the deployment.</p>
<aside class="note note-tip"><p>A site created by Cecil Desktop is a regular Netlify site: you can set its custom domain, redirects or forms in Netlify.</p></aside>]]>
    </content>
  </entry>
  <entry xml:lang="en">
    <id>https://desktop.cecil.app/docs/publishing/vercel/</id>
    <title>Vercel</title>
    <published>2026-11-09T10:53:41+00:00</published>
    <link href="https://desktop.cecil.app/docs/publishing/vercel/" rel="alternate" type="text/html" />
    <content type="html">
      <![CDATA[<h1>Vercel</h1>
<h2 id="token">Token<a class="heading-anchor" href="#token" aria-hidden="true" tabindex="-1"></a></h2>
<p>In Vercel, open <strong>Account settings › Tokens</strong> (the <strong>Create a token</strong> link of the form opens this page), and create a token with access to the team of the project.</p>
<p>The account is shown with the email of your Vercel user.</p>
<h2 id="target-settings">Target settings<a class="heading-anchor" href="#target-settings" aria-hidden="true" tabindex="-1"></a></h2>
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Project</strong></td>
<td>The name of the Vercel project.</td>
</tr>
<tr>
<td><strong>Team</strong></td>
<td>Optional: the ID (<code translate="no">team_…</code>) or the slug of the team, for a team project.</td>
</tr>
</tbody>
</table>
<p>When you save the target, only the access to the account (or to the team) is checked: the project is created at the first publication if it doesn't exist.</p>
<h2 id="publication">Publication<a class="heading-anchor" href="#publication" aria-hidden="true" tabindex="-1"></a></h2>
<p>The site is deployed to production, as a static site: Vercel doesn't run any build or install command, the files built by Cecil are published as they are. Only the files Vercel doesn't have yet are sent, then Cecil Desktop waits for the deployment (up to 5 minutes) and shows the URL of the project.</p>]]>
    </content>
  </entry>
  <entry xml:lang="en">
    <id>https://desktop.cecil.app/docs/publishing/github-pages/</id>
    <title>GitHub Pages</title>
    <published>2026-11-09T10:53:41+00:00</published>
    <link href="https://desktop.cecil.app/docs/publishing/github-pages/" rel="alternate" type="text/html" />
    <content type="html">
      <![CDATA[<h1>GitHub Pages</h1>
<h2 id="token">Token<a class="heading-anchor" href="#token" aria-hidden="true" tabindex="-1"></a></h2>
<p>GitHub Pages uses a <strong>fine-grained token</strong>: in GitHub, open <strong>Settings › Developer settings › Personal access tokens › Fine-grained tokens</strong> (the <strong>Create a token</strong> link of the form opens this page), then:</p>
<ol>
<li>under <strong>Repository access</strong>, choose <strong>Only select repositories</strong> and pick the repository of the site;</li>
<li>under <strong>Permissions</strong>, give <strong>Read and write</strong> access to <strong>Contents</strong> and <strong>Pages</strong>.</li>
</ol>
<p>The account is shown with your GitHub login.</p>
<h2 id="target-settings">Target settings<a class="heading-anchor" href="#target-settings" aria-hidden="true" tabindex="-1"></a></h2>
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Repository</strong></td>
<td>The repository, as <code translate="no">owner/repository</code>.</td>
</tr>
<tr>
<td><strong>Branch</strong></td>
<td>The published branch: <code translate="no">gh-pages</code> by default.</td>
</tr>
<tr>
<td><strong>Custom domain</strong></td>
<td>Optional: e.g. <code translate="no">www.example.com</code>.</td>
</tr>
</tbody>
</table>
<p>When you save the target, Cecil Desktop checks that the token can write to the repository.</p>
<h2 id="publication">Publication<a class="heading-anchor" href="#publication" aria-hidden="true" tabindex="-1"></a></h2>
<p>Each publication replaces the content of the branch with the built site, in a single commit (<em>Publish with Cecil Desktop</em>):</p>
<ul>
<li>the branch is created if it doesn't exist;</li>
<li>a <code translate="no">.nojekyll</code> file is added, so that GitHub doesn't process the site with Jekyll;</li>
<li>a <code translate="no">CNAME</code> file is added if you set a custom domain;</li>
<li>GitHub Pages is enabled on the branch if needed, or switched to it if it published another branch.</li>
</ul>
<p>Only the files GitHub doesn't have yet are sent, and the files removed from the site are removed from the branch. If nothing has changed, no commit is made.</p>
<aside class="note note-warning"><p>The published branch is overwritten at each publication: don't use the branch of your sources (e.g. <code translate="no">main</code>), keep a dedicated branch such as <code translate="no">gh-pages</code>.</p></aside>
<aside class="note note-tip"><p>When you create a site, Cecil Desktop can also add a GitHub Actions workflow that builds and deploys it on GitHub Pages at each push: an alternative to publishing from the app, if your site is in a GitHub repository.</p></aside>]]>
    </content>
  </entry>
  <entry xml:lang="en">
    <id>https://desktop.cecil.app/docs/publishing/aws-s3/</id>
    <title>AWS S3 / CloudFront</title>
    <published>2026-11-09T10:53:41+00:00</published>
    <link href="https://desktop.cecil.app/docs/publishing/aws-s3/" rel="alternate" type="text/html" />
    <content type="html">
      <![CDATA[<h1>AWS S3 / CloudFront</h1>
<h2 id="keys">Keys<a class="heading-anchor" href="#keys" aria-hidden="true" tabindex="-1"></a></h2>
<p>AWS uses the keys (<strong>Access key ID</strong> and <strong>Secret access key</strong>) of an IAM user. Create a user dedicated to the publication, with these permissions on the bucket:</p>
<ul>
<li><code translate="no">s3:ListBucket</code></li>
<li><code translate="no">s3:PutObject</code></li>
<li><code translate="no">s3:DeleteObject</code></li>
<li><code translate="no">cloudfront:CreateInvalidation</code>, if you use CloudFront</li>
</ul>
<p>A user limited to its bucket, that can't list the other buckets, is accepted. The account is shown as <em>AWS (ABCD…WXYZ)</em>, with the beginning and the end of the access key.</p>
<h2 id="target-settings">Target settings<a class="heading-anchor" href="#target-settings" aria-hidden="true" tabindex="-1"></a></h2>
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Bucket</strong></td>
<td>The name of the bucket.</td>
</tr>
<tr>
<td><strong>Region</strong></td>
<td>The region of the bucket, e.g. <code translate="no">eu-west-3</code>.</td>
</tr>
<tr>
<td><strong>Prefix</strong></td>
<td>Optional: a folder of the bucket, e.g. <code translate="no">docs/</code>.</td>
</tr>
<tr>
<td><strong>CloudFront distribution</strong></td>
<td>Optional: the ID of the distribution, to invalidate its cache after each publication.</td>
</tr>
<tr>
<td><strong>Site URL</strong></td>
<td>Optional: the public URL of the site, shown after each publication.</td>
</tr>
</tbody>
</table>
<aside class="note note-warning"><p>The bucket must exist: Cecil Desktop doesn't create it, and doesn't set its public access or its static website hosting. Set them up in AWS first.</p></aside>
<h2 id="publication">Publication<a class="heading-anchor" href="#publication" aria-hidden="true" tabindex="-1"></a></h2>
<p>The files are compared with the objects of the bucket (under the prefix):</p>
<ul>
<li>only the new and changed files are sent, with their content type;</li>
<li>the objects that are no longer in the site are <strong>deleted</strong>;</li>
<li>HTML pages are sent with cache headers that make browsers check for a new version, the other files are cached for 1 day;</li>
<li>if a CloudFront distribution is set and something has changed, its cache is invalidated.</li>
</ul>
<aside class="note note-caution"><p>Objects under the prefix that are not in the site are deleted: don't publish to a bucket (or a prefix) that holds other files.</p></aside>
<p>After the publication, the target shows the <strong>Site URL</strong>, or the URL of the <code translate="no">index.html</code> file in the bucket.</p>]]>
    </content>
  </entry>
</feed>
