Skip to content

Latest commit

 

History

History
407 lines (332 loc) · 12.5 KB

task.md

File metadata and controls

407 lines (332 loc) · 12.5 KB

Objective

Create a simple one-page static website with a non-technical editor UI at /admin/ using Decap CMS. Content is stored as Markdown (content/home.md) and rendered into HTML via Eleventy (11ty) at build time. Host on Netlify with auto-deploys from Git.

What to create (file tree) / ├─ package.json ├─ .eleventy.js ├─ netlify.toml ├─ README.md ├─ /admin/ │ ├─ index.html │ └─ config.yml ├─ /assets/ # CMS-uploaded images/files (in repo) ├─ /content/ │ └─ home.md # Single editable page (frontmatter + body) └─ /_includes/ └─ /layouts/ └─ home.njk # Template for the one-page site

Netlify will publish from ./_site (Eleventy’s default output).

Commands to support

npm install

npm run dev → local preview at http://localhost:8080 (11ty serve)

npm run build → static build to ./_site

Files — create with exact contents package.json { "name": "decap-onepage-netlify", "version": "1.0.0", "private": true, "scripts": { "dev": "npx @11ty/eleventy --serve", "build": "npx @11ty/eleventy" }, "devDependencies": { "@11ty/eleventy": "^2.0.0" } }

.eleventy.js module.exports = function(eleventyConfig) { // Copy CMS admin and assets straight through to _site eleventyConfig.addPassthroughCopy({ "admin": "admin" }); eleventyConfig.addPassthroughCopy({ "assets": "assets" });

// Set input/output return { dir: { input: ".", includes: "_includes", data: "_data", output: "_site" }, markdownTemplateEngine: "njk", htmlTemplateEngine: "njk", templateFormats: ["md", "njk", "html"] }; };

netlify.toml [build] command = "npm run build" publish = "_site"

optional: nice trailing-slash redirect for /admin

[[redirects]] from = "/admin" to = "/admin/" status = 301

admin/index.html <!doctype html>

<title>Content Admin</title> <script src="https://unpkg.com/decap-cms@^3.0.0/dist/decap-cms.js"></script>

admin/config.yml

If you’ll use Netlify Identity + Git Gateway, keep backend: git-gateway and enable both in the Netlify dashboard (Site → Identity → Enable; then Enable Git Gateway). If you prefer GitHub OAuth, change to backend: github and set repo: your-user/your-repo.

backend: name: git-gateway # or "github" branch: main

media_folder: "assets" # stored in repo public_folder: "/assets" # how site references them

publish_mode: editorial_workflow # allow drafts/review (optional)

collections:

  • label: "Homepage" name: "homepage" delete: false files:
    • label: "Home Content" name: "home" file: "content/home.md" fields:
      • { label: "Title", name: "title", widget: "string" }

      • { label: "Tagline", name: "tagline", widget: "string" }

      • { label: "Hero Image", name: "hero_image", widget: "image", required: false }

      • label: "Sections" name: "sections" widget: "list" types:

        • label: "Feature Grid" name: "feature_grid" widget: "object" fields:
          • { label: "Heading", name: "heading", widget: "string" }
          • label: "Items" name: "items" widget: "list" fields:
            • { label: "Title", name: "title", widget: "string" }
            • { label: "Description", name: "description", widget: "text" }
            • { label: "Icon", name: "icon", widget: "image", required: false }
        • label: "Testimonial" name: "testimonial" widget: "object" fields:
          • { label: "Quote", name: "quote", widget: "text" }
          • { label: "Author", name: "author", widget: "string" }
        • label: "Call to Action" name: "cta" widget: "object" fields:
          • { label: "Heading", name: "heading", widget: "string" }
          • { label: "Button Text", name: "button_text", widget: "string" }
          • { label: "Button Link", name: "button_href", widget: "string" }
      • label: "SEO" name: "seo" widget: "object" fields:

        • { label: "Meta Title", name: "meta_title", widget: "string" }
        • { label: "Meta Description", name: "meta_description", widget: "text" }
        • { label: "Social Image", name: "social_image", widget: "image", required: false }
      • { label: "Body", name: "body", widget: "markdown" }

content/home.md

layout: layouts/home.njk title: "Site Title" tagline: "One clear sentence about what this is" hero_image: "/assets/hero.jpg"

sections:

  • type: "feature_grid" heading: "What we do" items:

    • title: "Feature A" description: "Short blurb explaining A." icon: "/assets/icon-a.svg"
    • title: "Feature B" description: "Short blurb explaining B." icon: "/assets/icon-b.svg"
  • type: "testimonial" quote: "This product changed our workflows." author: "Alex C., Ops Lead"

  • type: "cta" heading: "Ready to talk?" button_text: "Contact us" button_href: "mailto:hello@example.com"

seo: meta_title: "Company — Clear Tagline" meta_description: "Short, keyword-rich description for search and link unfurls." social_image: "/assets/social-card.jpg"

Welcome to our site. This paragraph is the main body content shown near the top. You can edit everything on this page from the admin panel.

/_includes/layouts/home.njk <!doctype html>

<title>{{ seo.meta_title or title }}</title> {% if seo.meta_description %} {% endif %} {% if seo.social_image %} {% endif %} <style> :root { --max: 980px; } html,body { margin:0; padding:0; } body { font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif; line-height:1.6; color:#111; } header, main, footer { padding: 24px; } .wrap { max-width: var(--max); margin: 0 auto; } header.hero { padding-top: 56px; padding-bottom: 32px; text-align: center; } header.hero img { max-width: 100%; height: auto; border-radius: 16px; } h1 { font-size: clamp(28px, 4vw, 44px); margin: 16px 0 8px; } .tagline { color:#444; font-size: clamp(16px, 2.2vw, 20px); margin-bottom: 20px; } section { margin: 40px 0; } .grid { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); } .card { border: 1px solid #eee; border-radius: 16px; padding: 16px; box-shadow: 0 1px 2px rgba(0,0,0,.04); } .card h3 { margin: 0 0 8px; font-size: 18px; } .testimonial { font-style: italic; background: #fafafa; border-radius: 16px; padding: 20px; border: 1px solid #eee; } .cta { text-align: center; background: #0f62fe0d; border: 1px solid #cfe0ff; border-radius: 16px; padding: 24px; } .btn { display:inline-block; padding:12px 18px; border-radius: 999px; border: 1px solid #0f62fe; text-decoration:none; } .btn:hover { background:#0f62fe; color:#fff; } footer { color:#666; font-size:14px; border-top:1px solid #eee; } .body { margin-top: 16px; } img.icon { width: 32px; height: 32px; vertical-align: middle; margin-right: 8px; } </style>
{% if hero_image %} {% endif %}

{{ title }}

{% if tagline %}

{{ tagline }}

{% endif %} {% if content %}
{{ content | safe }}
{% endif %}
<main>
  <div class="wrap">
    {% if sections and sections.length %}
      {% for s in sections %}
        {% if s.type == "feature_grid" %}
          <section>
            {% if s.heading %}<h2>{{ s.heading }}</h2>{% endif %}
            <div class="grid">
              {% for it in s.items or [] %}
                <div class="card">
                  <h3>
                    {% if it.icon %}<img class="icon" src="{{ it.icon }}" alt="">{% endif %}
                    {{ it.title }}
                  </h3>
                  <p>{{ it.description }}</p>
                </div>
              {% endfor %}
            </div>
          </section>
        {% elif s.type == "testimonial" %}
          <section>
            <div class="testimonial">
              <p>“{{ s.quote }}”</p>
              <p><strong>— {{ s.author }}</strong></p>
            </div>
          </section>
        {% elif s.type == "cta" %}
          <section>
            <div class="cta">
              <h2>{{ s.heading }}</h2>
              {% if s.button_text and s.button_href %}
                <p><a class="btn" href="{{ s.button_href }}">{{ s.button_text }}</a></p>
              {% endif %}
            </div>
          </section>
        {% endif %}
      {% endfor %}
    {% endif %}
  </div>
</main>

<footer>
  <div class="wrap">
    <p>&copy; {{ (new Date()).getFullYear() }} {{ title }}</p>
  </div>
</footer>

README.md

One-Page Site with Decap CMS on Netlify

Overview

  • Edit at /admin/ (Decap CMS)
  • Content lives in content/home.md ( Markdown + frontmatter )
  • Built by Eleventy → static HTML → deployed on Netlify

Local Development

npm install
npm run dev
# open the served URL (usually http://localhost:8080)


Local CMS login requires either GitHub backend or running with Netlify Identity in production. For local content editing without auth, you can edit content/home.md directly.

Build
npm run build
# output in ./_site

Deploy to Netlify

Push this repo to GitHub/GitLab/Bitbucket.

In Netlify, New site from Git, pick your repo.

Build command: npm run build

Publish directory: _site

Deploy.

Enable Editor Login

Option A: Netlify Identity + Git Gateway (no GitHub app needed)

Netlify → Site → Identity → Enable Identity.

Click Invite Users (use your editors’ emails).

Netlify → Identity → Git Gateway → Enable Git Gateway.

Visit https://<yoursite>.netlify.app/admin/ to log in.

Option B: GitHub Backend

In admin/config.yml, set:

backend:
  name: github
  repo: your-user/your-repo
  branch: main


Create a GitHub OAuth app and set callback in Netlify (Site settings → Build & deploy → Environment → add required vars). Follow Decap GitHub backend docs.

Editors log in at /admin/.

Editing Content

Go to /admin/ → “Homepage” → “Home Content”

Change fields or upload images

Save → Publish

Netlify runs a new build; site updates after deploy completes

Notes

Images uploaded via the CMS are stored in /assets/ and deployed with the site.

You can rename sections or add types in admin/config.yml and map them in the layout template.


---

## How to run (for Claude to execute)

1. **Initialize project**
   - Create all files above with the exact contents.
   - Run `npm install`.

2. **Local preview**
   - `npm run dev`
   - Open the served URL (usually `http://localhost:8080`).

3. **First deploy**
   - Commit and push to your Git host.
   - Create a new Netlify site from this repo.
   - Build command: `npm run build`, Publish dir: `_site`.
   - Deploy.

4. **Enable login**
   - **Recommended:** Netlify Identity + Git Gateway.
   - Invite editors; they log in at `/admin/`.

5. **Handoff**
   - Share the site URL and `/admin/` with editors.
   - Keep `README.md` as your non-technical handoff doc.

---

## Done When
- `/` renders the one-page site from `content/home.md`.
- `/admin/` loads Decap CMS and allows editing + publishing.
- Publishing triggers Netlify builds and updates the live site.

---

**That’s the full, end-to-end setup.** If you want me to swap Eleventy for Astro or plain HTML + simple build, say the word and I’ll output a variant CLAUDE.md tailored to that stack.
::contentReference[oaicite:0]{index=0}