<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sébastien Conejo</title>
    <description>The latest articles on DEV Community by Sébastien Conejo (@sebconejo).</description>
    <link>https://dev.to/sebconejo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F621059%2F17b32c7b-92a7-4521-9f8f-f7e916877b44.png</url>
      <title>DEV Community: Sébastien Conejo</title>
      <link>https://dev.to/sebconejo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sebconejo"/>
    <language>en</language>
    <item>
      <title>My OpenClaw agent wouldn't stay autonomous. Here's what fixed it.</title>
      <dc:creator>Sébastien Conejo</dc:creator>
      <pubDate>Wed, 18 Mar 2026 19:36:13 +0000</pubDate>
      <link>https://dev.to/sebconejo/my-openclaw-agent-wouldnt-stay-autonomous-heres-what-fixed-it-4aoi</link>
      <guid>https://dev.to/sebconejo/my-openclaw-agent-wouldnt-stay-autonomous-heres-what-fixed-it-4aoi</guid>
      <description>&lt;p&gt;If you’ve set up automations in OpenClaw and they worked for a few hours then stopped silently, this is for you. The agent forgets its instructions, cron jobs show up empty, and you end up babysitting something that was supposed to be autonomous. I had the same problem. It took me a week of trial and error to get my agent to actually run on its own. If you’re hitting the same wall, here’s what fixed it for me.&lt;/p&gt;

&lt;p&gt;One thing before we start: don’t use OpenClaw to configure itself. Use Claude Code or any coding agent to write the skill files, the rules, the scripts. Then let OpenClaw execute them. OpenClaw is good at running systems but less at building them. Sometimes when I asked it to write its own config, something would be off or missing and I couldn’t figure out why. Building the files externally and dropping them into the workspace was just more predictable.&lt;/p&gt;

&lt;p&gt;Thanks for reading! Subscribe for free to receive new posts and support my work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The skill file
&lt;/h2&gt;

&lt;p&gt;Chat instructions don’t persist. You explain the tone you want, the agent nails it once, then forgets after compaction. Three sessions later it’s back to “Great thread! This is indeed a crucial topic in the AI landscape.”&lt;/p&gt;

&lt;p&gt;What helped most was putting the instructions into a skill file. A markdown file in your workspace that the agent reads before every action. Mine has four sections:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;identity (who the agent pretends to be on each platform),&lt;/li&gt;
&lt;li&gt;voice rules (max 2 sentences, no hashtags, no AI filler, with concrete good and bad examples),&lt;/li&gt;
&lt;li&gt;posting rules (when to mention my product and when not to),&lt;/li&gt;
&lt;li&gt;and anti-drift rules.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The anti-drift section seems to make the biggest difference so far. Re-read the skill file before every session. Start fresh every 3 posts. If something fails, stop and report instead of retrying. Log every action with SUCCESS or FAILED. Still early but the agent has been way more consistent since I added this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How I did it:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I wrote the full skill file in Claude Code, then told my agent&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Create a file at &lt;code&gt;skills/social-media-skill.md&lt;/code&gt; with this content:”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and pasted it in. Verify it’s there with:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Show me the content of &lt;code&gt;skills/social-media-skill.md&lt;/code&gt;.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Your agent lies
&lt;/h2&gt;

&lt;p&gt;I asked my agent to post a comment using the built-in browser tools. It came back:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I navigated to the post, typed the comment, clicked submit. The comment is live.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I went to check and saw… Nothing. I mean, an empty comment box. It hallucinated the entire sequence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What helped:&lt;/strong&gt; I stopped relying on the browser tools and used dedicated tools instead. For Reddit, I found a clean skill on ClawHub (by &lt;strong&gt;theglove44&lt;/strong&gt;) that uses Reddit’s API directly. I inspected the source before installing, one JS file, 16KB, no suspicious code, just standard Reddit API calls. For Twitter, I used xurl which handles the API natively. For anything that needed actual browser interaction, I wrote a Puppeteer script in Claude Code. In all three cases, the agent calls the tool, the tool does the work, returns a clear result, no hallucinated clicks!&lt;/p&gt;

&lt;p&gt;I also added a rule in my skill file: “Never say you completed an action unless you can show the tool output confirming it.” Much more reliable so far.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How I did it:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I wrote two scripts in Claude Code and dropped them in the workspace scripts folder. The first one, reddit-search.mjs, scans subreddits via Reddit’s public API and scores each post by opportunity (upvotes, velocity, number of comments, topic keywords). The second, reddit-comment.mjs, uses Puppeteer with my existing Chrome session to actually post comments, with verification at each step (login check, comment box found, submission confirmed). I also installed the Reddit skill via ClawHub for API-based reads, and updated the skill file to say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Do NOT use the browser tool to post. Use the scripts and skills only.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Both scripts are open source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/SebConejo/94a779aba89090d6bf81896df169c938#file-reddit-comment-mjs" rel="noopener noreferrer"&gt;reddit-comment.mjs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/SebConejo/94a779aba89090d6bf81896df169c938#file-reddit-search-mjs" rel="noopener noreferrer"&gt;reddit-search.mjs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Heartbeat and cron
&lt;/h2&gt;

&lt;p&gt;The heartbeat fires every 30 minutes and loads your full context each time. If your &lt;code&gt;HEARTBEAT.md&lt;/code&gt; says “check email, calendar, Twitter, memory, projects,” you’re burning a massive context window 48 times a day.&lt;/p&gt;

&lt;p&gt;Cron jobs run at specific times in isolated sessions. I use heartbeat for monitoring only and cron for actions. I have two cron jobs: daytime posts every 9-24 minutes with variation, nighttime posts hourly with a 3-hour quiet window.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How I did it:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I told my agent “Create two cron jobs” with the exact schedule I wanted. Then I verified they actually existed by running openclaw cron status in my terminal. If it shows jobs: 0, the agent didn’t create them even if it said it did. Keep asking until the number matches what you requested.&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory breaks silently
&lt;/h2&gt;

&lt;p&gt;When conversations get long, OpenClaw compacts them. The summary loses things. The agent forgets your corrections and starts drifting without telling you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How I did it:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I told my agent&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Add this rule to &lt;code&gt;AGENTS.md&lt;/code&gt;: before any compaction, save the 5 most important facts from the current session to &lt;code&gt;memory/YYYY-MM-DD.md&lt;/code&gt;.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I also created a separate log file for my specific use case (&lt;code&gt;memory/social-media-log.md&lt;/code&gt;) so the agent has a concrete record of what it posted instead of relying on its own memory.&lt;/p&gt;

&lt;p&gt;Verify with: “Show me the content of &lt;code&gt;AGENTS.md&lt;/code&gt;” and check the rule is there.&lt;/p&gt;

&lt;h2&gt;
  
  
  One agent, one task
&lt;/h2&gt;

&lt;p&gt;I started by trying to do everything at once. Multiple platforms, multiple personas. The agent got confused fast and the quality dropped.&lt;/p&gt;

&lt;p&gt;What worked: one agent focused on one task only. It becomes good at that one thing. Once it’s stable and consistent, I can duplicate the approach for another task with a separate agent. Not before.&lt;/p&gt;

&lt;h2&gt;
  
  
  The files that matter
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;SOUL.md&lt;/code&gt;: personality. &lt;code&gt;AGENTS.md&lt;/code&gt;: rules and memory protection. &lt;code&gt;HEARTBEAT.md&lt;/code&gt;: monitoring only. Skill file: how to post, voice rules, anti-drift. Social media log: every action with results. Two cron jobs: day schedule and night schedule.&lt;/p&gt;

&lt;p&gt;I’m still iterating on all of this, but so far each change made a noticeable difference. If you’re building something similar, I hope this saves you some of the trial and error.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>openclaw</category>
      <category>programming</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>How to stop burning money on OpenClaw</title>
      <dc:creator>Sébastien Conejo</dc:creator>
      <pubDate>Tue, 03 Mar 2026 00:10:45 +0000</pubDate>
      <link>https://dev.to/sebconejo/how-to-stop-burning-money-on-openclaw-2ngo</link>
      <guid>https://dev.to/sebconejo/how-to-stop-burning-money-on-openclaw-2ngo</guid>
      <description>&lt;p&gt;OpenClaw is one of the fastest-growing open-source projects in recent history. 230,000 GitHub stars, 116,000 Discord members, 2 million visitors per week. All of that in two months. People are running personal AI agents on their Mac Minis and cloud servers. It works, and it is genuinely useful.&lt;/p&gt;

&lt;p&gt;Like any major shift in how we use technology, it comes with constraints. After speaking with over a hundred OpenClaw users, cost is the topic that comes up in almost every conversation. Someone sets up their agent, starts using it daily, and two weeks later discovers they have spent $254 on API tokens. Another spent $800 in a month. These are not power users pushing the limits. These are normal setups with normal usage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the money goes
&lt;/h2&gt;

&lt;p&gt;Your agent sends every request to your primary model. A heartbeat check, a calendar lookup, a simple web search. If your primary model is Opus 4.6, all of it goes through the most expensive endpoint available.&lt;/p&gt;

&lt;p&gt;Your costs stack up from four main sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;System context&lt;/strong&gt; - &lt;code&gt;SOUL.md&lt;/code&gt; loads into the prompt on every call. Other bootstrap files like &lt;code&gt;AGENTS.md&lt;/code&gt; contribute depending on what the agent needs. Even with memory pulled in through search rather than loaded raw, the base system context still adds up. On a typical setup, you are looking at thousands of tokens billed on every single request.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Conversation history&lt;/strong&gt; - Your history grows with every exchange. After a few hours of active use, a session can carry a large amount of tokens. The entire history tags along with every new request.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Heartbeat checks&lt;/strong&gt; - The heartbeat runs in the background every 30 minutes by default. Each check is a full API call with all of the above included.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Model choice&lt;/strong&gt; - Without routing, every request is sent to a single primary model, whether the task is simple or complex. That prevents cost optimization.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One user woke up to an unexpected $141 bill overnight because the heartbeat was hitting the wrong model.&lt;/p&gt;

&lt;p&gt;Put all of this together on an unoptimized Opus setup and you can easily spend more per day than most people expect to pay in a month.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ficucg65jhk3fd4jl86sj.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ficucg65jhk3fd4jl86sj.gif" alt=" " width="600" height="263"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Use one agent with skills instead of many agents
&lt;/h2&gt;

&lt;p&gt;This is the highest-impact change you can make and almost nobody talks about it.&lt;/p&gt;

&lt;p&gt;A lot of users build multi-agent setups. One agent for writing, one for research, one for coding, one to coordinate. Each agent runs as a separate instance with its own memory, its own context, and its own configuration files. Every handoff between agents burns tokens. Each agent adds its own fixed context overhead, so costs scale with every new instance you spin up.&lt;/p&gt;

&lt;p&gt;OpenClaw has a built-in alternative. A skill is a markdown file that gives your agent a new capability without creating a new instance. Same brain, same memory, same context. One user went from spending hundreds per week on a multi-agent setup to $90 per month with a single agent and a dozen skills. The quality went up because context stopped getting lost between handoffs.&lt;/p&gt;

&lt;p&gt;Keep one main agent. Give it a skill for each type of work. Only spin up a sub-agent for background tasks that take several minutes and need to run in parallel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Route each task to the right model
&lt;/h2&gt;

&lt;p&gt;The majority of what your agent does is simple. Status checks, message formatting, basic lookups. These do not need a frontier model. Only a small fraction of requests actually benefits from premium reasoning.&lt;/p&gt;

&lt;p&gt;Without routing, all of it hits your most expensive endpoint by default. One deployment tracked their costs before and after implementing routing and went from $150 per month to $35. Another went from $347 to $68. Smart routing tools can reduce costs by 70 percent on average.&lt;/p&gt;

&lt;p&gt;OpenClaw does not ship with a built-in routing engine, so you need an external tool to make this work. &lt;a href="https://manifest.build" rel="noopener noreferrer"&gt;Manifest&lt;/a&gt; handles this out of the box. It classifies each request and routes it to the right model automatically, so your heartbeats and simple lookups go to Haiku while complex reasoning still hits Opus. That alone cuts your bill dramatically without any manual config per task.&lt;/p&gt;

&lt;p&gt;If you prefer a DIY approach, you can set up multiple model configs or write a routing skill yourself, but it takes more effort to get right.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr9q4o0hlapo1paqsotzb.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr9q4o0hlapo1paqsotzb.gif" alt=" " width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Cache what does not change
&lt;/h2&gt;

&lt;p&gt;Your &lt;code&gt;SOUL.md&lt;/code&gt;, &lt;code&gt;MEMORY.md&lt;/code&gt;, and system instructions are the same from one call to the next. Without caching, the provider processes all of those tokens from scratch on every single request. You pay full price every time for content that has not changed.&lt;/p&gt;

&lt;p&gt;Prompt caching is a capability on the provider side. Anthropic offers an explicit prompt caching mechanism with a documented TTL where cached reads cost significantly less than fresh processing. Other providers handle caching differently or automatically, so the details depend on which model you are using. The point is the same: static tokens that hit warm cache cost less than tokens processed from scratch.&lt;/p&gt;

&lt;p&gt;This is where the heartbeat becomes relevant. If your heartbeat fires often enough to keep the provider's cache warm between calls, every check reuses the cached system context instead of reprocessing it from zero. Cache TTLs vary by provider and configuration. Anthropic's standard TTL is around 5 minutes, with longer windows available depending on the setup. Community members have found that aligning the heartbeat interval just under whichever TTL you are working with keeps the cache alive. Combine that with routing your heartbeat to a cheap model and each background check costs a fraction of what it would on a cold Opus call.&lt;/p&gt;

&lt;p&gt;The key principle is simple. Make sure your static content (system instructions, bootstrap files) sits at the beginning of your prompt and variable content comes at the end. That structure maximizes what the provider can cache. One user documented a drop from $720 to $72 per month primarily through this approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shrink your context window
&lt;/h2&gt;

&lt;p&gt;Every message you send includes your full conversation history. After a few hours that history alone can cost more than the actual answer. Three things you can do about it.&lt;/p&gt;

&lt;p&gt;Start new conversations often. This is the easiest win. Instead of running one conversation for an entire day, start a fresh one every couple of hours. Your agent keeps its long-term memory across conversations but drops the accumulated back-and-forth. Context resets to your bootstrap files only.&lt;/p&gt;

&lt;p&gt;Clean up your &lt;code&gt;SOUL.md&lt;/code&gt;. Everything in that file loads on every single call. If you have task-specific instructions sitting next to your personality rules, you are paying for all of it every time. Move the specialized parts into skills. They only load when the agent actually needs them.&lt;/p&gt;

&lt;p&gt;Optimize how memory loads into context. OpenClaw uses memory_search to pull relevant memories into your prompt, not the raw file. But the more memories accumulate over weeks of use, the more context those searches can return. Configuring the QMD backend and tuning what gets retrieved keeps that footprint tight. Some community members have built structured memory layers on top of this and cut their base context to a fraction of what it used to be.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run a local model for the simple stuff
&lt;/h2&gt;

&lt;p&gt;Running a model on your own hardware eliminates API costs for the tasks that do not need a cloud model.&lt;/p&gt;

&lt;p&gt;You pay for hardware once. After that, every inference is free. For heartbeats, classification, and routine lookups, local models are more than capable.&lt;/p&gt;

&lt;p&gt;The popular choice right now is Qwen 3 32B. On an RTX 4090 it runs at 40+ tokens per second. A Mac Mini running 24/7 handles the lightweight workload while cloud models only get called for complex reasoning.&lt;/p&gt;

&lt;p&gt;Ollama makes the integration simple. Install, pull the model, point your OpenClaw config at the local endpoint for specific task types. It works through an OpenAI-compatible HTTP endpoint.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fooiy3oyu3ytqqnnarslu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fooiy3oyu3ytqqnnarslu.png" alt=" " width="800" height="640"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Track your costs daily
&lt;/h2&gt;

&lt;p&gt;Every user who cut their bill says the same thing. The fix was not a specific technique. It was seeing where the money went.&lt;/p&gt;

&lt;p&gt;Checking your bill once a month hides everything. You miss the day a cron job misfired. You miss the skill that routes to Opus when it should hit Haiku.&lt;/p&gt;

&lt;p&gt;Use an observability tool that shows you per-prompt, per-model cost breakdowns. When you can see exactly which request went to which model and what it cost, problems become obvious. The fixes usually take minutes once you see the data.&lt;/p&gt;

&lt;p&gt;Some routing tools offer real-time tracking with daily budgets and alerts so you catch problems before they compound. Your provider dashboard already tracks spending, but the granularity varies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to start
&lt;/h2&gt;

&lt;p&gt;Start with visibility. Set up an observability tool so you can see which prompts cost what and which models they hit. You cannot optimize what you cannot measure.&lt;/p&gt;

&lt;p&gt;If you are running multiple agents, switch to one agent with skills. That is the highest return for the least effort.&lt;/p&gt;

&lt;p&gt;Route your heartbeat to a cheap model. This alone makes a noticeable difference on a 24/7 agent.&lt;/p&gt;

&lt;p&gt;Enable prompt caching. It takes minutes to set up.&lt;/p&gt;

&lt;p&gt;Keep your context lean. Clean up your &lt;code&gt;SOUL.md&lt;/code&gt;, start new conversations regularly, and switch your memory to vector search.&lt;/p&gt;

&lt;p&gt;Add a local model if you have the hardware. It handles heartbeats and simple tasks at zero marginal cost.&lt;/p&gt;

&lt;p&gt;Based on what we've observed across multiple OpenClaw deployments, applying these changes can reduce monthly costs by five.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you're running OpenClaw agents and want to keep costs under control, we built &lt;a href="https://manifest.build" rel="noopener noreferrer"&gt;Manifest&lt;/a&gt; for that. It's free, open source, and gives you real-time cost tracking with smart model routing. Feedback is welcome, we're building this with the community.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>openclaw</category>
      <category>ai</category>
      <category>infrastructure</category>
      <category>llm</category>
    </item>
    <item>
      <title>The OpenClaw ecosystem is exploding. I mapped the key players actually gaining traction.</title>
      <dc:creator>Sébastien Conejo</dc:creator>
      <pubDate>Tue, 03 Mar 2026 00:04:45 +0000</pubDate>
      <link>https://dev.to/sebconejo/the-openclaw-ecosystem-is-exploding-i-mapped-the-key-players-actually-gaining-traction-3hp1</link>
      <guid>https://dev.to/sebconejo/the-openclaw-ecosystem-is-exploding-i-mapped-the-key-players-actually-gaining-traction-3hp1</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsl9ov7edn3ja6j3oydhu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsl9ov7edn3ja6j3oydhu.png" alt=" " width="800" height="687"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I curated the key players shaping the OpenClaw ecosystem, just 2 months after launch.&lt;/p&gt;

&lt;p&gt;What's happening around OpenClaw is unlike anything I've seen in open-source AI.&lt;/p&gt;

&lt;p&gt;In 60 days:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;230K+ GitHub stars&lt;/li&gt;
&lt;li&gt;116K+ Discord members&lt;/li&gt;
&lt;li&gt;ClawCon touring globally (SF, Berlin, Tokyo...)&lt;/li&gt;
&lt;li&gt;A dedicated startup validation platform (TrustMRR)&lt;/li&gt;
&lt;li&gt;And an entire ecosystem of companies, tools and integrations forming around a single open-source project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Managed hosting, LLM routing, security layers, agent social networks, skill marketplaces. New categories are emerging in real time.&lt;/p&gt;

&lt;p&gt;Some of these players are barely weeks old. And established companies like OpenRouter, LiteLLM or VirusTotal are building native integrations.&lt;/p&gt;

&lt;p&gt;I mapped the ones that matter right now: The Claw Market Map, Q1 2026 Edition.&lt;/p&gt;

&lt;p&gt;If you're a VC looking at AI infra, an operator deploying agents, or a founder building in this space, this is the landscape today.&lt;/p&gt;

&lt;p&gt;Most of what's on this map didn't exist 60 days ago.&lt;/p&gt;

&lt;p&gt;This is what happens when an open-source project ships with the right primitives at the right time. The community doesn't just adopt, it builds.&lt;/p&gt;

&lt;p&gt;I'll keep updating this map. If you're a key player in the OpenClaw ecosystem and I missed you, drop a comment.&lt;/p&gt;

</description>
      <category>openclaw</category>
      <category>agents</category>
      <category>openai</category>
      <category>llm</category>
    </item>
    <item>
      <title>The OpenClaw ecosystem is exploding. I mapped the key players actually gaining traction.</title>
      <dc:creator>Sébastien Conejo</dc:creator>
      <pubDate>Fri, 27 Feb 2026 18:59:07 +0000</pubDate>
      <link>https://dev.to/sebconejo/the-openclaw-ecosystem-is-exploding-i-mapped-the-key-players-actually-gaining-traction-52bi</link>
      <guid>https://dev.to/sebconejo/the-openclaw-ecosystem-is-exploding-i-mapped-the-key-players-actually-gaining-traction-52bi</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F57ljn703c4grk3lzu1qx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F57ljn703c4grk3lzu1qx.png" alt=" " width="800" height="687"&gt;&lt;/a&gt;&lt;br&gt;
I curated the key players shaping the OpenClaw ecosystem, just 2 months after launch.&lt;/p&gt;

&lt;p&gt;What's happening around OpenClaw is unlike anything I've seen in open-source AI.&lt;/p&gt;

&lt;p&gt;In 60 days:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;230K+ GitHub stars&lt;/li&gt;
&lt;li&gt;116K+ Discord members&lt;/li&gt;
&lt;li&gt;ClawCon touring globally (SF, Berlin, Tokyo...)&lt;/li&gt;
&lt;li&gt;A dedicated startup validation platform (TrustMRR)&lt;/li&gt;
&lt;li&gt;And an entire ecosystem of companies, tools and integrations forming around a single open-source project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Managed hosting, LLM routing, security layers, agent social networks, skill marketplaces. New categories are emerging in real time.&lt;/p&gt;

&lt;p&gt;Some of these players are barely weeks old. And established companies like OpenRouter, LiteLLM or VirusTotal are building native integrations.&lt;/p&gt;

&lt;p&gt;I mapped the ones that matter right now: The Claw Market Map, Q1 2026 Edition.&lt;/p&gt;

&lt;p&gt;If you're a VC looking at AI infra, an operator deploying agents, or a founder building in this space, this is the landscape today.&lt;/p&gt;

&lt;p&gt;Most of what's on this map didn't exist 60 days ago.&lt;/p&gt;

&lt;p&gt;This is what happens when an open-source project ships with the right primitives at the right time. The community doesn't just adopt, it builds.&lt;/p&gt;

&lt;p&gt;I'll keep updating this map. If you're a key player in the OpenClaw ecosystem and I missed you, drop a comment.&lt;/p&gt;

</description>
      <category>openclaw</category>
      <category>agents</category>
      <category>openai</category>
      <category>llm</category>
    </item>
    <item>
      <title>I built an open-source alternative to OpenRouter that runs on your machine for your OPenClaw 🦞</title>
      <dc:creator>Sébastien Conejo</dc:creator>
      <pubDate>Fri, 27 Feb 2026 03:43:13 +0000</pubDate>
      <link>https://dev.to/sebconejo/i-built-an-open-source-alternative-to-openrouter-that-runs-on-your-machine-for-your-openclaw-25jg</link>
      <guid>https://dev.to/sebconejo/i-built-an-open-source-alternative-to-openrouter-that-runs-on-your-machine-for-your-openclaw-25jg</guid>
      <description>&lt;p&gt;Stop overpaying for your OpenClaw usage!&lt;/p&gt;

&lt;p&gt;There is a way to drastically reduce your costs. It is Manifest! A free open-source platform that intercepts every prompt and routes it to the appropriate model that can handle it.&lt;/p&gt;

&lt;p&gt;The platform gives you real-time cost per prompt, model and message so you always know where your tokens go. You can set budget alerts and usage limits.&lt;/p&gt;

&lt;p&gt;Everything runs locally on your machine. We never collect your messages or prompts, only metadata for telemetry.&lt;br&gt;
The platform is fully open source and self-hostable. If you prefer not to run it locally we also have a cloud version.&lt;/p&gt;

&lt;p&gt;Our goal is to give every OpenClaw user full control over their agent spending.&lt;/p&gt;

&lt;p&gt;We just shipped this and will improve it with the community. If you try it out we'd genuinely love your feedback on GitHub or Discord. Tell us what's broken, what's missing, what you'd want next. It would help a lot. 🙏&lt;/p&gt;

&lt;p&gt;&lt;a href="https://manifest.build/" class="crayons-btn crayons-btn--primary" rel="noopener noreferrer"&gt;Our website&lt;/a&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/mnfst/manifest" rel="noopener noreferrer"&gt;Our Github&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>openclaw</category>
      <category>agents</category>
      <category>deepseek</category>
      <category>apigateway</category>
    </item>
    <item>
      <title>I built a platform that enables AI agents to execute complex tasks</title>
      <dc:creator>Sébastien Conejo</dc:creator>
      <pubDate>Sat, 14 Feb 2026 23:08:21 +0000</pubDate>
      <link>https://dev.to/sebconejo/i-built-a-platform-that-enables-ai-agents-to-execute-complex-tasks-2j5</link>
      <guid>https://dev.to/sebconejo/i-built-a-platform-that-enables-ai-agents-to-execute-complex-tasks-2j5</guid>
      <description>&lt;p&gt;Hey everyone,&lt;/p&gt;

&lt;p&gt;With OpenClaw, Claude Code, Codex CLI, agents are getting incredibly good at reasoning. But they still struggle with certain actions. Booking a restaurant, scraping a page, filling out a complex form. They break down when precision, sequencing, and reliability actually matter.&lt;/p&gt;

&lt;p&gt;We're building a platform where your OpenClaw agent can call purpose built services designed to execute high precision tasks reliably.-&amp;gt; &lt;a href="https://manifest.new" rel="noopener noreferrer"&gt;https://manifest.new&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If this resonates and you’ve had to look for services or build something to make your agents work better, I’d love to hear about it in the comments.&lt;/p&gt;

</description>
      <category>openclaw</category>
      <category>agents</category>
      <category>webdev</category>
      <category>ai</category>
    </item>
    <item>
      <title>🔥 5 Epic Tools To Launch Your MVP Now</title>
      <dc:creator>Sébastien Conejo</dc:creator>
      <pubDate>Fri, 22 Aug 2025 15:21:32 +0000</pubDate>
      <link>https://dev.to/sebconejo/5-epic-tools-to-launch-your-mvp-now-1emm</link>
      <guid>https://dev.to/sebconejo/5-epic-tools-to-launch-your-mvp-now-1emm</guid>
      <description>&lt;p&gt;Whether you’re a solo founder, an indie hacker, or a CTO, one thing matters more than anything: shipping fast. Thanks to AI, a new wave of tools makes it possible to go from idea to product in record time. &lt;/p&gt;

&lt;p&gt;We’ve picked 5 that cut out the usual pain and let you move straight to building.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxwahde8lc7p252s7v0nw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxwahde8lc7p252s7v0nw.gif" alt="Let's go"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://uploadthing.com/" rel="noopener noreferrer"&gt;UploadThing&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9bx91l0ubheloye13jye.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9bx91l0ubheloye13jye.png" alt="UploadThing website cover"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://uploadthing.com/" rel="noopener noreferrer"&gt;UploadThing&lt;/a&gt; is a modern alternative to S3 built for developers. It handles the heavy lifting of file storage and delivery while giving you a type-safe API, a CDN, and simple routes you control from your code.&lt;/p&gt;

&lt;p&gt;You decide what files can be uploaded, add auth and metadata with middleware, and process results on completion. It integrates with all major frontend frameworks and has backend adapters for Express, Fastify, H3 and more.&lt;/p&gt;

&lt;p&gt;A clean developer-first way to add secure file uploads without the usual S3 pain.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://uploadthing.com/" class="crayons-btn crayons-btn--primary" rel="noopener noreferrer"&gt;Try it out&lt;/a&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;a href="https://manifest.build/" rel="noopener noreferrer"&gt;Manifest&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F34ud5z6d0193tgvf7kxm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F34ud5z6d0193tgvf7kxm.png" alt="Manifest website cover"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://manifest.build/" rel="noopener noreferrer"&gt;Manifest&lt;/a&gt; is an open source backend to ship fast. It allows you to define your backend in a single file. It has simple code approach easy for developers to read and write and easy for LLMs to generate.&lt;/p&gt;

&lt;p&gt;Most existing backend tools are painful. They are bloated, they force you into endless configuration, and they lock you into complexe dashboards. Manifest takes the opposite path. You just describe your backend in a YAML file to instantly get data, logic, auth, storage and an admin UI.&lt;/p&gt;

&lt;p&gt;It runs self-hosted out of the box with SQLite, Postgres, MySQL or MariaDB. A Cloud version with AI is coming soon. It will take you from an idea to a production backend instantly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://manifest.build/" class="crayons-btn crayons-btn--primary" rel="noopener noreferrer"&gt;Try it out&lt;/a&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;a href="https://copycoder.ai/" rel="noopener noreferrer"&gt;CopyCoder&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb9n22qdvg3fyjv56s4do.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb9n22qdvg3fyjv56s4do.png" alt="CopyCoder website cover"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://copycoder.ai/" rel="noopener noreferrer"&gt;CopyCoder&lt;/a&gt; is an AI-powered tool that lets you clone and scaffold complete web applications in minutes. By uploading screenshots of your target app, CopyCoder generates optimized prompts that can be run directly in Cursor to build a working frontend almost instantly.  &lt;/p&gt;

&lt;p&gt;And by the way, it works perfectly with Manifest, presented just above. Install Manifest to your project in Cursor and let the chat spin up the backend for your frontend.&lt;/p&gt;

&lt;p&gt;Perfect for solo founders who want to turn ideas into production-ready apps without wasting time on boilerplate.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://copycoder.ai/" class="crayons-btn crayons-btn--primary" rel="noopener noreferrer"&gt;Try it out&lt;/a&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;a href="https://tally.so/" rel="noopener noreferrer"&gt;Tally&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzp0jwdpd5x37ebtrtvtd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzp0jwdpd5x37ebtrtvtd.png" alt="Tally website cover"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tally.so/" rel="noopener noreferrer"&gt;Tally&lt;/a&gt; is the simplest way to create online forms without coding. It works like Notion but instead of blocks you add fields, type your questions and build a form in seconds.&lt;/p&gt;

&lt;p&gt;You get unlimited forms and submissions for free with advanced features like conditional logic, payment collection, file uploads, e-signatures, hidden fields and integrations with tools like Notion, Google Sheets, Airtable and Zapier.&lt;/p&gt;

&lt;p&gt;When you publish your form, you get a shareable link and all the responses land in your dashboard. It gives you exactly what you need when you want to ship a prototype with a form to test an idea or collect insights from real users.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tally.so/" class="crayons-btn crayons-btn--primary" rel="noopener noreferrer"&gt;Try it out&lt;/a&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;a href="https://rork.com/" rel="noopener noreferrer"&gt;Rork&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3zfznj42qqhywe3u7pnk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3zfznj42qqhywe3u7pnk.png" alt="Rork website cover"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://rork.com/" rel="noopener noreferrer"&gt;Rork&lt;/a&gt; is an AI-powered no-code platform focused on mobile apps. You describe your idea in plain English and it generates a working iOS and Android app using React Native and Expo. You can preview your app instantly in the browser or on your phone with Expo Go, then publish it to the app stores.&lt;/p&gt;

&lt;p&gt;It’s especially useful if you want to ship a mobile app quickly, whether it’s a social app or a fitness tracker. You can also import Figma designs and iterate with prompts.&lt;/p&gt;

&lt;p&gt;There’s no free plan though, you’ll need a paid subscription starting at about 25€ per month to export and actually use the apps you generate.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://rork.com/" class="crayons-btn crayons-btn--primary" rel="noopener noreferrer"&gt;Try it out&lt;/a&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;These 5 tools remove the friction that usually slows you down and give you the shortest path from idea to product.&lt;/p&gt;

&lt;p&gt;If you need to ship a product fast whether it is an app, a prototype, an MVP or even to win a hackathon these tools will save you precious time. &lt;/p&gt;

&lt;p&gt;If you use them let me know what you think in the comments and feel free to suggest other tools &lt;/p&gt;

&lt;p&gt;😉 Thank you&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffq7thrp3ebsu70v37t40.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffq7thrp3ebsu70v37t40.gif" alt="Thank you"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mvp</category>
      <category>hackathon</category>
      <category>programming</category>
      <category>resources</category>
    </item>
    <item>
      <title>Build a backend with Cursor and Manifest in just 5 minutes 😱</title>
      <dc:creator>Sébastien Conejo</dc:creator>
      <pubDate>Mon, 23 Jun 2025 18:10:26 +0000</pubDate>
      <link>https://dev.to/sebconejo/build-a-backend-with-cursor-and-manifest-in-just-5-minutes-3m74</link>
      <guid>https://dev.to/sebconejo/build-a-backend-with-cursor-and-manifest-in-just-5-minutes-3m74</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;In this article, I’ll show you how to build a backend in under 5 minutes using &lt;a href="https://manifest.build" rel="noopener noreferrer"&gt;Manifest&lt;/a&gt; directly from your &lt;a href="https://cursor.sh/" rel="noopener noreferrer"&gt;Cursor&lt;/a&gt; IDE.&lt;/p&gt;

&lt;p&gt;We’ll start from a static real estate listing app and replace static data with a fully functional backend: data, filters, CRUD, and admin panel!&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;If you’re experimenting with &lt;strong&gt;AI-powered development&lt;/strong&gt;, you’ve probably seen two types of tools emerge.&lt;/p&gt;

&lt;p&gt;First, there are &lt;strong&gt;vibe coding tools&lt;/strong&gt; like Lovable or Bolt. They’re great at turning a short prompt into a polished UI. For quick prototypes, they feel magical. But when it comes to integrating a backend, they hit a wall. You stay stuck with mock data without backend logic.&lt;/p&gt;

&lt;p&gt;The second are &lt;strong&gt;AI code editors&lt;/strong&gt; like &lt;strong&gt;Cursor&lt;/strong&gt; or &lt;strong&gt;Windsurf&lt;/strong&gt;. These let you code with assistance, directly in your environment. But even then, generating the backend is where problems start.&lt;/p&gt;

&lt;p&gt;The AI spreads logic across too many files. Once you iterate, it introduces strange changes that are hard to track. Reviewing everything becomes exhausting, and you can’t really trust that the result is secure. You still need backend skills to understand what was generated and make sure nothing breaks or leaks.&lt;/p&gt;

&lt;p&gt;You might consider using one of the many no-code BaaS platforms. Some of them now offer MCPs to bridge the gap between visual tools and AI code editors, but their core experience is still tied to their studio. Even with those improvements, you end up switching back and forth, breaking your flow and slowing down iteration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi7yrooyb3k664ir1d69g.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi7yrooyb3k664ir1d69g.webp" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Manifest solves this by allowing you to &lt;strong&gt;code&lt;/strong&gt; or &lt;strong&gt;vibe-code a backend instantly&lt;/strong&gt;. No drag and drop. Just 1 YAML file easy to read and edit both by &lt;strong&gt;developers&lt;/strong&gt; and &lt;strong&gt;LLMs&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before getting started, make sure you have &lt;a href="https://nodejs.org/en" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; installed on your machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Used Tools
&lt;/h2&gt;

&lt;p&gt;Here’s an overview of the tools we’ll be working with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://cursor.dev/" rel="noopener noreferrer"&gt;Cursor&lt;/a&gt;: An &lt;strong&gt;AI-powered code editor&lt;/strong&gt;. In this tutorial, we’ll use it with its default LLM, Claude Sonnet 3.5.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://manifest.build/" rel="noopener noreferrer"&gt;Manifest&lt;/a&gt;: Manifest is the backend for developers who want to ship fast. We will use it to create instantly a backend with data, storage, logic and an admin panel.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fits naturally into AI-assisted coding. No bloated no-code UI&lt;/li&gt;
&lt;li&gt;Easy and safe to validate&lt;/li&gt;
&lt;li&gt;Reduce LLM token usage by up to 90%&lt;/li&gt;
&lt;li&gt;The fastest way to build a backend.&lt;/li&gt;
&lt;li&gt;It's open source and can be self-hosted effortlessly.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://manifest.build" class="crayons-btn crayons-btn--primary" rel="noopener noreferrer"&gt;→ Try Manifest&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Project setup
&lt;/h2&gt;

&lt;p&gt;We’ll start from an existing frontend that displays a few real estate listings using static sample data.&lt;/p&gt;

&lt;p&gt;Our goal is to replace this static data with a backend powered by &lt;strong&gt;Manifest&lt;/strong&gt;. We'll keep the existing structure and avoid adding unnecessary complexity. So the data can be managed by administrators.&lt;/p&gt;

&lt;p&gt;Now, let’s take a quick look at how the current frontend works before installing the backend.&lt;/p&gt;

&lt;p&gt;The current UI is a simple real estate listing page. It displays a few sample properties with basic details like title, image, price, surface and more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxxsuxr3avejq6bn2nrrm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxxsuxr3avejq6bn2nrrm.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The project has a &lt;code&gt;client/&lt;/code&gt; folder that contains the frontend. It was generated using &lt;a href="https://bolt.new/" rel="noopener noreferrer"&gt;bolt.new&lt;/a&gt;, which gives us a nice starter to work with and allows us to stay focus on the backend work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F46gba6lzxxqbq0qn8in1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F46gba6lzxxqbq0qn8in1.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each property follows a consistent structure defined in a &lt;code&gt;types/Property.ts&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbpc0e9icbdplgsd6y3m5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbpc0e9icbdplgsd6y3m5.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The sample data is located in &lt;code&gt;data/properties.ts&lt;/code&gt;. This is the static content we’ll replace with real data from our backend.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgoy5pfx322ykopad0vmy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgoy5pfx322ykopad0vmy.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These properties are rendered using a &lt;code&gt;PropertyList&lt;/code&gt; component.    &lt;/p&gt;

&lt;p&gt;Now that we’ve seen how the frontend works, let’s install Manifest and bring it to life.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Manifest
&lt;/h2&gt;

&lt;p&gt;Manifest is designed to integrate directly into your AI code editor. It doesn’t require any external dashboard or setup flow. Everything lives in a single YAML configuration file.&lt;/p&gt;

&lt;p&gt;From the root of your project, run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn create manifest server --cursor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a &lt;code&gt;server/&lt;/code&gt; folder containing your backend Manifest.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb7ijdmgg00r0n0zhpko5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb7ijdmgg00r0n0zhpko5.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the folder is generated, open &lt;code&gt;manifest/backend.yml&lt;/code&gt;. In this YAML file, you should see a default template of a backend, called &lt;code&gt;My pet app&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Now, let’s ask Cursor to generate the backend for our real estate app.&lt;/p&gt;

&lt;p&gt;Here’s the prompt I used:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsulvrwal3v8v3oeaqkja.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsulvrwal3v8v3oeaqkja.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cursor replies with a YAML file describing your backend. In my case, it named the project: &lt;code&gt;name: Real Estate Listing App 🏠&lt;/code&gt; and defined the three core entities: Property, Agent and Inquiry.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# This is a sample file for a backend.yml manifest backend.&lt;/span&gt;
&lt;span class="c1"&gt;# Read more about the manifest format here: https:/manifest.build/docs&lt;/span&gt;

&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Real Estate Listing App 🏠&lt;/span&gt;
&lt;span class="na"&gt;entities&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;Property&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;title&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;price&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;number&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;location&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;city&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;bedrooms&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;number&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;bathrooms&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;number&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;surfaceArea&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;number&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;description&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;image&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
          &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;choice&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="nv"&gt;options&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;values&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;House'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Apartment'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Studio'&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt; &lt;span class="pi"&gt;},&lt;/span&gt;
        &lt;span class="pi"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;belongsTo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Agent&lt;/span&gt;
    &lt;span class="na"&gt;policies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;read&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;access&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;public&lt;/span&gt;

  &lt;span class="na"&gt;Agent&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;name&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;email&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;phone&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;photo&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;image&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;policies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;read&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;access&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;public&lt;/span&gt;
      &lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;access&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;public&lt;/span&gt;

  &lt;span class="na"&gt;Inquiry&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;name&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;email&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;message&lt;/span&gt;
    &lt;span class="na"&gt;belongsTo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Property&lt;/span&gt;
    &lt;span class="na"&gt;policies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;read&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;access&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;public&lt;/span&gt;
      &lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;access&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;public&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The assistant also explains its choices, especially the access policies.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2kbx4i6mpsmohqnvpzcy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2kbx4i6mpsmohqnvpzcy.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s accept this version for now.&lt;/p&gt;

&lt;p&gt;To start the backend and access the generated API and admin panel, just run:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm run manfiest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Once it’s up, go to &lt;code&gt;http://localhost:1111/api&lt;/code&gt; to explore your API routes and test them in the Swagger interface.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0tmtgzst145pls7rz5l4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0tmtgzst145pls7rz5l4.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also explore the admin panel by visiting:  &lt;a href="http://localhost:1111/" rel="noopener noreferrer"&gt;http://localhost:1111&lt;/a&gt;&lt;br&gt;
Here, you’ll find all your entities listed with a full interface to manage your data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc18t511u77vczcpq1pwg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc18t511u77vczcpq1pwg.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Try creating a few residences and agents directly from the UI. You’ll instantly see them appear in your API responses too. On my side, I seeded mock data running &lt;code&gt;npm run manifest:seed&lt;/code&gt; from the server repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbf1vwy9mtls3b0ilbrpk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbf1vwy9mtls3b0ilbrpk.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that the backend is running, it’s time to connect the frontend to real data.&lt;/p&gt;
&lt;h2&gt;
  
  
  Connect the frontend to the backend
&lt;/h2&gt;

&lt;p&gt;Let’s replace the static content with real data from our backend.&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Install the Manifest SDK
&lt;/h3&gt;

&lt;p&gt;We can use either the REST API or the SDK. For this tutorial, I chose to use the SDK. To do so, run this command in your client folder:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;br&gt;
npm i @mnfst/sdk&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Once installed, we can use the SDK to fetch the data from our backend.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;App.vue&lt;/code&gt;, replace the static data import with a real API call using the SDK:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Manifest&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@mnfst/sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This imports the Manifest SDK. It allows us to interact with the backend.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;manifest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Manifest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a new instance of the Manifest client. It will automatically connect to the local server running on &lt;code&gt;localhost:1111&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;properties&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Property&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;([])&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we set up reactive state:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;properties&lt;/code&gt; will hold the residences fetched from the backend.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;loading&lt;/code&gt; lets us show a loading state while we wait.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;error&lt;/code&gt; will capture any issue if the request fails.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;onMounted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;manifest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;residences&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;perPage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="nx"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Unknown error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code runs when the component mounts. It fetches up to 100 &lt;code&gt;properties&lt;/code&gt; from the backend and stores them in the &lt;code&gt;properties&lt;/code&gt; array. If something goes wrong, we store the error message.&lt;/p&gt;

&lt;p&gt;For now, we keep it simple by fetching everything in one request. We could add pagination later using the &lt;code&gt;page&lt;/code&gt; and &lt;code&gt;perPage&lt;/code&gt; options provided by Manifest.&lt;/p&gt;

&lt;p&gt;You’ll also need to update the template to reflect the loading and error states:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;loading&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;loading&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Loading&lt;/span&gt; &lt;span class="nx"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PropertyList&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;properties&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A loading message is shown while we wait for the data&lt;/li&gt;
&lt;li&gt;An error message appears if the fetch fails&lt;/li&gt;
&lt;li&gt;The property list only renders once the data is available&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now your frontend is powered by backend data and ready for the next step. Let’s take a look at the result in the browser:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fos318pv1pqecr7xbip0y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fos318pv1pqecr7xbip0y.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What we’ve got so far
&lt;/h2&gt;

&lt;p&gt;At this point, your frontend is fully connected to a real backend.&lt;br&gt;&lt;br&gt;
You can browse residences, apply filters, and manage listings in a clean admin interface.&lt;/p&gt;

&lt;p&gt;What’s most interesting is how little code we had to write for the backend:&lt;/p&gt;

&lt;p&gt;Most of the logic lives in a single YAML file. That’s what makes Manifest a perfect match for an AI code editor like Cursor.&lt;/p&gt;

&lt;p&gt;✅ The LLM gets a clear, structured context to work with. &lt;br&gt;
✅ It can generate reliable changes without scattering logic across the project.&lt;br&gt;
✅ You stay in control and iterate faster.&lt;/p&gt;

&lt;p&gt;This was the main goal of this tutorial: show how fast and safe it can be to bring real data into a frontend project, thanks to how naturally Manifest integrates into your AI coding environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Want to go further?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Manifest supports essential backend features like file &lt;strong&gt;uploads&lt;/strong&gt;, &lt;strong&gt;authentication&lt;/strong&gt;, &lt;strong&gt;custom hooks&lt;/strong&gt; and so on.&lt;/p&gt;

&lt;p&gt;The full version of this project with inquiry forms and email is available on GitHub:  &lt;/p&gt;

&lt;p&gt;→ &lt;strong&gt;&lt;a href="https://github.com/SebConejo/real-estate-example" rel="noopener noreferrer"&gt;github.com/SebConejo/real-estate-example&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Manifest is an open source young project.&lt;br&gt;
It’s evolving fast thanks to the feedback we get from early users. We’d love to hear what you’re building, what’s missing, and what you’d like us to add next.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Try it here:&lt;/strong&gt; &lt;a href="https://manifest.build/" rel="noopener noreferrer"&gt;manifest.build&lt;/a&gt;&lt;br&gt;&lt;br&gt;
⭐️ &lt;strong&gt;Star us on GitHub:&lt;/strong&gt; &lt;a href="https://github.com/mnfst/manifest" rel="noopener noreferrer"&gt;github.com/mnfst/manifest&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>api</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>7 insanely fast dev tools to build, deploy, and move on ⚡🔥</title>
      <dc:creator>Sébastien Conejo</dc:creator>
      <pubDate>Thu, 06 Feb 2025 21:45:31 +0000</pubDate>
      <link>https://dev.to/sebconejo/7-insanely-fast-dev-tools-to-build-deploy-and-move-on-kao</link>
      <guid>https://dev.to/sebconejo/7-insanely-fast-dev-tools-to-build-deploy-and-move-on-kao</guid>
      <description>&lt;h2&gt;
  
  
  &lt;a href="https://www.trae.ai/" rel="noopener noreferrer"&gt;Trae&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6dwcsqmikvsbgexvyqw9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6dwcsqmikvsbgexvyqw9.png" alt="Image description" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.trae.ai/" rel="noopener noreferrer"&gt;Trae&lt;/a&gt; is an AI-powered IDE designed to boost developer productivity by offering intelligent code suggestions, debugging assistance, and optimization tools. It combines a sleek interface with advanced AI to help developers write and refine code faster and more efficiently. Trae supports multiple languages and frameworks, making it a versatile tool for both prototyping and production-level coding. While it’s not affiliated with &lt;strong&gt;TikTok&lt;/strong&gt;, its seamless integration and AI-driven features position it as a strong contender in the developer tools space, rivaling popular IDEs like &lt;strong&gt;VS Code with Copilot&lt;/strong&gt;, or &lt;strong&gt;&lt;a href="https://www.cursor.com/" rel="noopener noreferrer"&gt;Cursor&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.trae.ai/" class="ltag_cta ltag_cta--branded" rel="noopener noreferrer"&gt;Try it out 🔥&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://manifest.build" rel="noopener noreferrer"&gt;Manifest&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2lx6vvzdyz4501c3en18.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2lx6vvzdyz4501c3en18.png" alt="Image description" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://manifest.build" rel="noopener noreferrer"&gt;Manifest&lt;/a&gt; is a &lt;strong&gt;minimalist, streamlined Backend-as-a-Service (BaaS)&lt;/strong&gt; designed for speed and simplicity. It lets you &lt;strong&gt;define your backend in a single YAML file&lt;/strong&gt;, instantly getting a &lt;strong&gt;REST API, a database, an SDK, and an admin panel&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;No complex setups. No unnecessary configuration. Just a &lt;strong&gt;lightweight backend&lt;/strong&gt; that gets out of your way, so you can build and deploy faster than ever.&lt;/p&gt;

&lt;p&gt;Here’s how effortlessly you can define a backend:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my portfolio&lt;/span&gt;
&lt;span class="na"&gt;entities&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;Project&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;title&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;description&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;role&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;score&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;number&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;date&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;date&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;link&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
          &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;photo&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
          &lt;span class="nv"&gt;options&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;{&lt;/span&gt;
              &lt;span class="nv"&gt;sizes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="pi"&gt;{&lt;/span&gt;
                  &lt;span class="nv"&gt;small&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;403&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;805&lt;/span&gt; &lt;span class="pi"&gt;},&lt;/span&gt;
                  &lt;span class="nv"&gt;large&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;806&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;1610&lt;/span&gt; &lt;span class="pi"&gt;},&lt;/span&gt;
                &lt;span class="pi"&gt;},&lt;/span&gt;
            &lt;span class="pi"&gt;},&lt;/span&gt;
        &lt;span class="pi"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;Contacts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;name&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;email&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;message&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;text&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Yes, this is the entire backend of a portfolio. Crazy, right? I actually put it to the test in my latest article: &lt;a href="https://dev.to/sebconejo/i-built-a-portfolio-in-minutes-with-bolt-and-manifest-4lcn"&gt;I Built a Portfolio in Minutes with Bolt and Manifest&lt;/a&gt;. Check it out! 🚀.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://manifest.build" class="ltag_cta ltag_cta--branded" rel="noopener noreferrer"&gt;Try it out 🔥&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://mermaid.js.org/" rel="noopener noreferrer"&gt;Mermaid&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1eyjom3z1kdt0zplglik.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1eyjom3z1kdt0zplglik.png" alt="Image description" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mermaid.js.org/" rel="noopener noreferrer"&gt;Mermaid&lt;/a&gt; is an open-source JavaScript library that allows users to generate diagrams and charts from plain text in a simple and intuitive way.&lt;strong&gt; Using a Markdown-like syntax, it enables the creation of flowcharts, sequence diagrams, Gantt charts, and more, directly within documentation or code. &lt;/strong&gt;Its main advantage** lies in its ease of integration and ability to automate visual creation, making it an ideal tool for developers and technical teams looking to add charts easily.&lt;/p&gt;

&lt;p&gt;Mermaid.js is a &lt;strong&gt;JavaScript-based diagramming tool&lt;/strong&gt; that lets you &lt;strong&gt;write&lt;/strong&gt; flowcharts, sequence diagrams, Gantt charts, and more—using a simple markdown-like syntax.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart LR
    A[Hard] --&amp;gt;|Text| B(Round)
    B --&amp;gt; C{Decision}
    C --&amp;gt;|One| D[Result 1]
    C --&amp;gt;|Two| E[Result 2]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above generates the following chart. I love it!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc8xr7yzva9v8b9ubqmoc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc8xr7yzva9v8b9ubqmoc.png" alt="Image description" width="800" height="309"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Perfect for &lt;strong&gt;technical documentation, dashboards, and wikis&lt;/strong&gt;, it integrates seamlessly with Markdown-based platforms like Notion, GitHub, and Docusaurus.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mermaid.js.org/" class="ltag_cta ltag_cta--branded" rel="noopener noreferrer"&gt;Try it out 🔥&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://sevalla.com/" rel="noopener noreferrer"&gt;Sevalla&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frsbn7yi7jb6e7pr7e4bs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frsbn7yi7jb6e7pr7e4bs.png" alt="Image description" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://sevalla.com/" rel="noopener noreferrer"&gt;Sevalla&lt;/a&gt; is a modern alternative to Heroku that makes it easy to deploy and manage applications, databases, and static sites, with support for Git, Docker, and Cloudflare for fast and optimized deployments. Its streamlined workflow eliminates unnecessary complexity, allowing developers to focus on building rather than configuring.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://sevalla.com/" class="ltag_cta ltag_cta--branded" rel="noopener noreferrer"&gt;Try it out 🔥&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://keystatic.com/" rel="noopener noreferrer"&gt;Keystatic&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F375u6mr62ya77q1d1fbs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F375u6mr62ya77q1d1fbs.png" alt="Image description" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://keystatic.com/" rel="noopener noreferrer"&gt;Keystatic&lt;/a&gt; is a &lt;strong&gt;Git-based headless CMS&lt;/strong&gt; that lets developers and content teams &lt;strong&gt;manage structured content in flat files&lt;/strong&gt;, without needing a database.&lt;/p&gt;

&lt;p&gt;No databases, no backend! Just structured content stored directly in your repo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://keystatic.com/" class="ltag_cta ltag_cta--branded" rel="noopener noreferrer"&gt;Try it out 🔥&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://lovable.dev/" rel="noopener noreferrer"&gt;Lovable&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwrcvy4wwa0jpm5rlrd2q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwrcvy4wwa0jpm5rlrd2q.png" alt="Image description" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://lovable.dev/" rel="noopener noreferrer"&gt;Lovable&lt;/a&gt; is an &lt;strong&gt;AI-powered Full Stack Engineer&lt;/strong&gt; that makes app development &lt;strong&gt;very fast&lt;/strong&gt; and effortless, without writing a single line of code. It connects seamlessly with platforms like &lt;a href="https://supabase.com/" rel="noopener noreferrer"&gt;Supabase&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;By transforming &lt;strong&gt;natural language prompts into fully functional applications&lt;/strong&gt;, Lovable significantly reduces development time. It supports &lt;strong&gt;large codebases&lt;/strong&gt; and offers a rich collection of &lt;strong&gt;templates&lt;/strong&gt;. Whether you're a &lt;strong&gt;beginner or an experienced developer&lt;/strong&gt;, Lovable helps you &lt;strong&gt;turn ideas into working products with minimal effort&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://lovable.dev/" class="ltag_cta ltag_cta--branded" rel="noopener noreferrer"&gt;Try it out 🔥&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://orm.drizzle.team/" rel="noopener noreferrer"&gt;Drizzle&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftzstw4ov8r1eb8mkh5vq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftzstw4ov8r1eb8mkh5vq.png" alt="Image description" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://orm.drizzle.team/" rel="noopener noreferrer"&gt;Drizzle&lt;/a&gt; is a &lt;strong&gt;lightweight, high-performance ORM for TypeScript&lt;/strong&gt; that provides &lt;strong&gt;a type-safe, SQL-first approach to database management&lt;/strong&gt;. It supports &lt;strong&gt;PostgreSQL, MySQL, SQLite, and SQL Server&lt;/strong&gt; while prioritizing &lt;strong&gt;speed, simplicity, and full TypeScript integration&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Unlike traditional ORMs, Drizzle follows a &lt;strong&gt;data-mapper pattern&lt;/strong&gt;, allowing &lt;strong&gt;direct control over queries without abstractions&lt;/strong&gt;. Its &lt;strong&gt;fluent API&lt;/strong&gt; makes writing SQL &lt;strong&gt;intuitive, safe, and efficient&lt;/strong&gt;, making it an ideal choice for &lt;strong&gt;serverless applications, high-performance APIs, and SQL-focused projects&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://orm.drizzle.team/" class="ltag_cta ltag_cta--branded" rel="noopener noreferrer"&gt;Try it out 🔥&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Ready to build better?
&lt;/h2&gt;

&lt;p&gt;In 2025, speed and simplicity are the keys to efficient development. Tools like Manifest, Keystatic, and Drizzle strip away unnecessary complexity, while Lovable and Trae AI introduce automation to supercharge your workflow. These tools help you build, deploy, and move on—without the bloat.&lt;/p&gt;

&lt;p&gt;Which of these tools will you try first? Let me know in the comments! 🚀&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxcpzcedgpzghgsbllkps.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxcpzcedgpzghgsbllkps.png" alt="Image description" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you found this article useful, share it with your peers and community.&lt;/p&gt;

&lt;p&gt;Got other awesome projects in mind? Drop them in the comments! 👇&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>ai</category>
      <category>beginners</category>
    </item>
    <item>
      <title>I built a portfolio in minutes with Bolt and Manifest</title>
      <dc:creator>Sébastien Conejo</dc:creator>
      <pubDate>Mon, 03 Feb 2025 20:15:37 +0000</pubDate>
      <link>https://dev.to/sebconejo/i-built-a-portfolio-in-minutes-with-bolt-and-manifest-4lcn</link>
      <guid>https://dev.to/sebconejo/i-built-a-portfolio-in-minutes-with-bolt-and-manifest-4lcn</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;In this article, I'll show you how to build a complete portfolio with a backend to manage your projects. We'll use &lt;a href="https://bolt.new/" rel="noopener noreferrer"&gt;bolt&lt;/a&gt; for the frontend and &lt;a href="https://manifest.build/" rel="noopener noreferrer"&gt;Manifest&lt;/a&gt; to spin up a backend in seconds. No complexity, no bloat—just a fast, efficient, and streamlined workflow. Your portfolio will be ready to deploy in minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;As developers, We often need to build content-driven websites like blogs, portfolios, or showcases, whether for personal use or clients. Most backend solutions are &lt;strong&gt;bloated&lt;/strong&gt;. They require long setups, endless tutorials, and unnecessary complexity just to get started.&lt;/p&gt;

&lt;p&gt;Building a modern portfolio with content management shouldn’t be a burden. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Manifest&lt;/strong&gt; fixes this. No over-engineering, no wasted time. Just a backend that works instantly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7nd6xfiy0p0041dtxpgp.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7nd6xfiy0p0041dtxpgp.gif" alt="Image description" width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before getting started, make sure you have &lt;a href="https://nodejs.org/en" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; and &lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;npm&lt;/a&gt; installed on your machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Used Tools
&lt;/h2&gt;

&lt;p&gt;Here’s an overview of the tools We’ll be working with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://bolt.new/" rel="noopener noreferrer"&gt;Bolt.new&lt;/a&gt;: To generate a portfolio frontend from a simple prompt.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://manifest.build/" rel="noopener noreferrer"&gt;Manifest&lt;/a&gt;: To generate a complete backend. It includes a documented API, a database, an admin panel with authentication, and storage for images, and much more.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting Up the Project
&lt;/h2&gt;

&lt;p&gt;The goal here is to show you how to easily add a backend to any frontend. I won’t go into too much detail on frontend development. Instead, I’ll simply add a backend to a random portfolio frontend generated by Bolt.new.&lt;/p&gt;

&lt;h3&gt;
  
  
  Initializing the Frontend with Bolt.new
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Let's start by generating the frontend. Head over to bolt.new and enter a prompt. I used: 'Create a beautiful one-page portfolio with a contact form.'&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bolt will then generate a set of specs. We can iterate on them until we're happy with the proposed frontend.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Overview of our portfolio
&lt;/h4&gt;

&lt;p&gt;After a few iterations, I ended up with the following portfolio.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkzt828f1phlc0cyagee5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkzt828f1phlc0cyagee5.gif" alt="Image description" width="576" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s take a look at the project’s code. The generated structure is clean, with each section of the site having its own .tsx component. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdeikp1ffbognbujln2x3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdeikp1ffbognbujln2x3.png" alt="Image description" width="454" height="700"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These files handle only the frontend. There's no &lt;strong&gt;business logic&lt;/strong&gt; yet. We'll use &lt;strong&gt;Manifest&lt;/strong&gt; to add a &lt;strong&gt;backend&lt;/strong&gt; and make the projects dynamic.&lt;/p&gt;

&lt;p&gt;Bolt doesn't yet have direct integration with Manifest, but adding it manually is still quick and easy. ⚡&lt;/p&gt;

&lt;h3&gt;
  
  
  Initialize the backend with manifest
&lt;/h3&gt;

&lt;p&gt;Still from bolt.new, we'll open a second terminal and install manifest using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;  &lt;span class="n"&gt;npx&lt;/span&gt; &lt;span class="k"&gt;add&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;manifest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After installing the backend, a Manifest repository appears at the root of the project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxzusjp0qxyydp96layz7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxzusjp0qxyydp96layz7.png" alt="Image description" width="318" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, let’s define our data model. Since projects are defined by the following fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Project title&lt;/li&gt;
&lt;li&gt;Image with two different sizes&lt;/li&gt;
&lt;li&gt;Description&lt;/li&gt;
&lt;li&gt;External link&lt;/li&gt;
&lt;li&gt;Role&lt;/li&gt;
&lt;li&gt;Date&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's open the &lt;code&gt;manifest/backend.yml&lt;/code&gt; file and replace the existing code with this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my portfolio&lt;/span&gt;
    &lt;span class="s"&gt;entities&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;Project&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;title&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;description&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;role&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;date&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;date&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;link&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
              &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;photo&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
              &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
              &lt;span class="nv"&gt;options&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="pi"&gt;{&lt;/span&gt;
                  &lt;span class="nv"&gt;sizes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                    &lt;span class="pi"&gt;{&lt;/span&gt;
                      &lt;span class="nv"&gt;small&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;403&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;805&lt;/span&gt; &lt;span class="pi"&gt;},&lt;/span&gt;
                      &lt;span class="nv"&gt;large&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;806&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;1610&lt;/span&gt; &lt;span class="pi"&gt;},&lt;/span&gt;
                    &lt;span class="pi"&gt;},&lt;/span&gt;
                &lt;span class="pi"&gt;},&lt;/span&gt;
            &lt;span class="pi"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;Contacts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;name&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;email&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;message&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;text&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Starting the backend
&lt;/h2&gt;

&lt;p&gt;Still from our second terminal, We run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;  &lt;span class="n"&gt;manifest&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="n"&gt;dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the backend is up and running, the terminal provides two links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🖥️ Admin panel: &lt;a href="http://localhost:1111" rel="noopener noreferrer"&gt;http://localhost:1111&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📚 API documentation: &lt;a href="http://localhost:1111/api" rel="noopener noreferrer"&gt;http://localhost:1111/api&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From the "preview" button in bolt, We can choose to view either the portfolio frontend, the admin panel, or the API documentation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi55om8okv838ewfla76o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi55om8okv838ewfla76o.png" alt="Image description" width="800" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's open the admin panel (&lt;a href="http://localhost:1111" rel="noopener noreferrer"&gt;http://localhost:1111&lt;/a&gt;) and log in using the pre-filled credentials.&lt;/p&gt;

&lt;p&gt;In the admin panel sidebar, We'll click on "Collections", then, "Projects". We should now see an empty list of projects.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh1nujoglt0d5r4s8vagc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh1nujoglt0d5r4s8vagc.png" alt="Image description" width="800" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's click "Create a new project", fill in all the fields, and submit the project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9990e21mjzt2f7opbhgn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9990e21mjzt2f7opbhgn.png" alt="Image description" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once our project is submitted, We should see it appear in the project list.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjtx91f0i1tvwg1yi61oc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjtx91f0i1tvwg1yi61oc.png" alt="Image description" width="800" height="192"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Replacing static data with dynamic content
&lt;/h2&gt;

&lt;p&gt;Now, we need to replace the static projects with data from the backend. The first step is to install the Manifest SDK so we can interact with our backend.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing the Manifest SDK
&lt;/h3&gt;

&lt;p&gt;Open another terminal and install the manifest SDK:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;npm&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="n"&gt;@mnfst&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sdk&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Use the Manifest JS SDK to fetch our data
&lt;/h3&gt;

&lt;p&gt;Once the installation is complete, We'll open the work.tsx file and take a look.&lt;/p&gt;

&lt;p&gt;This file contains:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Static data&lt;/li&gt;
&lt;li&gt;The HTML structure displaying that data
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;work&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tsx&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ExternalLink&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lucide-react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;FadeIn&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../animations/FadeIn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;projects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;photo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;large&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://via.placeholder.com/800x450&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;small&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://via.placeholder.com/400x225&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Modern E-Commerce Platform&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;An intuitive e-commerce solution for small businesses.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Lead Designer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2023-06-15&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://example.com/case-study-1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;photo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;large&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://via.placeholder.com/800x450&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;small&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://via.placeholder.com/400x225&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AI-Powered Analytics Dashboard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A comprehensive analytics tool leveraging AI.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Frontend Developer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2022-11-10&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://example.com/case-study-2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;photo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;large&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://via.placeholder.com/800x450&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;small&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://via.placeholder.com/400x225&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Creative Portfolio Website&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A portfolio showcasing creative work in digital design.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Full Stack Developer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2021-09-20&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://example.com/case-study-3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Work&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"work"&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"py-32 bg-white"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"container mx-auto px-6"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FadeIn&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-4xl md:text-5xl font-bold mb-16 text-center"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            Selected Work
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;FadeIn&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"space-y-32"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;projects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FadeIn&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"group"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;
                  &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`grid md:grid-cols-3 gap-12 items-center &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;
                    &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;md:grid-flow-dense&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;
                  &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;
                    &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`md:col-span-2 &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;
                      &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;md:col-start-2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                  &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"relative aspect-[16/9] overflow-hidden rounded-xl"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt;
                        &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;photo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;large&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;photo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;small&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                        &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                        &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"w-full h-full object-cover bg-slate-100 transition-transform duration-700 group-hover:scale-105"&lt;/span&gt;
                      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
                    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

                  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"space-y-6"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-3xl font-bold"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-gray-600 text-lg leading-relaxed"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

                    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"flex flex-col gap-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-sm text-gray-500"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Role&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-lg font-medium"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-sm text-gray-500"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Date&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-lg font-medium"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;
                        &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                        &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"inline-flex items-center gap-2 text-blue-600 hover:text-blue-700 font-medium"&lt;/span&gt;
                      &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                        View Case Study &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ExternalLink&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
                      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;FadeIn&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To connect &lt;code&gt;work.tsx&lt;/code&gt; to the backend, We first need to import the manifest SDK. Let's add this import at the top of the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Manifest&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;@mnfst&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sdk&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, We'll add the types/types.ts file and define the project interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Project&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="nl"&gt;photo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;large&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;small&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;  
  &lt;span class="nl"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;  
  &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;  
  &lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;  
  &lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;  
  &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;  

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This file provides a clear and reusable type definition for projects.&lt;/p&gt;

&lt;p&gt;Next, in work.tsx, We'll remove the static code. In my case, it looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;
&lt;span class="cm"&gt;/* [...] */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;projects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;photo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;large&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://via.placeholder.com/800x450&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;small&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://via.placeholder.com/400x225&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Modern E-Commerce Platform&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;An intuitive e-commerce solution for small businesses.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Lead Designer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2023-06-15&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://example.com/case-study-1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;photo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;large&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://via.placeholder.com/800x450&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;small&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://via.placeholder.com/400x225&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AI-Powered Analytics Dashboard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A comprehensive analytics tool leveraging AI.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Frontend Developer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2022-11-10&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://example.com/case-study-2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Work&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="cm"&gt;/* [...] */&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and replace it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* [...] */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Manifest&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@mnfst/sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Project&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../types/types&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Work&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;projects&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setProjects&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Project&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;([])&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchProjects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;manifest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Manifest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:1111&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;paginator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;manifest&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;projects&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;orderBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;date&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;desc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;projects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;paginator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Project&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
      &lt;span class="nf"&gt;setProjects&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;projects&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;fetchProjects&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="cm"&gt;/* [...] */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I used two React hooks to manage the data flow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;useState: Handles local state inside a functional component.&lt;/li&gt;
&lt;li&gt;useEffect: Runs code in response to state changes, component mounting, or unmounting.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's check the portfolio interface. The newly added project should now appear.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl5rnd45xrjlcjh1yb8tm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl5rnd45xrjlcjh1yb8tm.png" alt="Image description" width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At this point, the static content has been &lt;strong&gt;successfully replaced with dynamic data&lt;/strong&gt; from &lt;strong&gt;Manifest&lt;/strong&gt;! 🚀&lt;/p&gt;

&lt;p&gt;Projects are now loaded directly from the database and displayed dynamically on the frontend.&lt;/p&gt;

&lt;p&gt;Even better, it's now possible to &lt;strong&gt;add, edit, or delete&lt;/strong&gt; projects directly from the admin panel! 🎯&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;With just a few steps, we’ve turned a static portfolio into a dynamic, fully managed application. What’s powerful here isn’t just the speed of setup—it’s the flexibility this approach provides.&lt;/p&gt;

&lt;p&gt;This isn’t just about portfolios. The same workflow can be applied to blogs, dashboards, or any content-driven project. With Manifest handling the backend, you’re free to iterate, scale, and focus on the frontend experience rather than backend maintenance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;With the project ready, the next logical step is to download it and push it to GitHub before deployment. This ensures proper version control and makes future updates easier.&lt;/p&gt;

&lt;p&gt;Manifest is built for speed and simplicity. From setup to deployment, everything is designed to be as smooth and effortless as possible. Deployment is just as fast. With a few steps, your backend is live. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://manifest.build/docs/deploy-fly-io" rel="noopener noreferrer"&gt;Deploy on Fly.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://manifest.build/docs/deploy-digital-ocean" rel="noopener noreferrer"&gt;Deploy on Digital Ocean&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://manifest.build/docs/deploy-render-com" rel="noopener noreferrer"&gt;Deploy on Render&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://manifest.build/docs/deploy-heroku" rel="noopener noreferrer"&gt;Deploy on Heroku&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Plus, Manifest Cloud is in development, allowing you to deploy instantly, without any setup. If you want to be notified when this feature launches, sign up here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://manifest.build/#cta-cloud" class="ltag_cta ltag_cta--branded" rel="noopener noreferrer"&gt;→ Manifest Cloud waitlist&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;🔹 &lt;a href="https://stackblitz.com/edit/portfolio-vitejs-manifest?file=manifest%2Fbackend.yml" rel="noopener noreferrer"&gt;Live portfolio on StackBlitz&lt;/a&gt;&lt;br&gt;
🔹 &lt;a href="https://github.com/SebConejo/portfolio-vite-manifest" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you found this post useful, feel free to share it with others who might appreciate it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fohr6tce3qemuizf81dh5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fohr6tce3qemuizf81dh5.png" alt="Image description" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vite</category>
      <category>opensource</category>
      <category>ai</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>10 game-changing tools that level up Svelte developers in 2025 💪</title>
      <dc:creator>Sébastien Conejo</dc:creator>
      <pubDate>Sun, 20 Oct 2024 11:48:02 +0000</pubDate>
      <link>https://dev.to/sebconejo/10-game-changing-tools-that-level-up-svelte-developers-in-2025-14g3</link>
      <guid>https://dev.to/sebconejo/10-game-changing-tools-that-level-up-svelte-developers-in-2025-14g3</guid>
      <description>&lt;p&gt;The Svelte ecosystem is growing faster than ever, and with it comes a wave of amazing tools that can supercharge your development workflow. What makes these tools special is how they align with Svelte's core philosophy: simplicity, efficiency, and developer experience. Like Svelte itself, each tool in this list delivers powerful functionality while maintaining a clean, focused approach.&lt;/p&gt;

&lt;p&gt;Here's a curated list of open-source gems that deserve a spot in your toolbox.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. &lt;a href="https://www.warp.dev/" rel="noopener noreferrer"&gt;Warp&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6nkqv6a0vfj2pmq9tl4u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6nkqv6a0vfj2pmq9tl4u.png" alt="Warp terminal" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.warp.dev/" rel="noopener noreferrer"&gt;Warp&lt;/a&gt; is a terminal built for the 21st century. It features collaborative workflows, modern design, and is blazing fast. Its interface offers an intuitive experience, including features like real-time for pair programming, syntax highlighting, and auto-completion. Warp’s philosophy is centered around efficiency and performance, which is perfect for Svelte developers who like to move fast and stay productive.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. &lt;a href="https://www.skeleton.dev/" rel="noopener noreferrer"&gt;Skeleton&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffr14ollu1tta9rfe5vdf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffr14ollu1tta9rfe5vdf.png" alt="Skeleton website" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.skeleton.dev/" rel="noopener noreferrer"&gt;Skeleton&lt;/a&gt; is more than just another UI library - it's a complete design system for Svelte that emphasizes developer experience and performance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fully-featured component library&lt;/li&gt;
&lt;li&gt;Tailwind CSS integration&lt;/li&gt;
&lt;li&gt;Dark mode out of the box&lt;/li&gt;
&lt;li&gt;Built-in themes and customization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/skeletonlabs/skeleton" class="ltag_cta ltag_cta--branded" rel="noopener noreferrer"&gt;Github repository →&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  3. &lt;a href="https://manifest.build" rel="noopener noreferrer"&gt;Manifest&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj7psfindvw1beppavmuu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj7psfindvw1beppavmuu.png" alt="Manifest - A complete backend in 1 YAML file" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://manifest.build" rel="noopener noreferrer"&gt;Manifest&lt;/a&gt; is an incredibly easy-to-use backend, ideal for being integrated into Svelte projects. Just with a  YAML file, you create an entire backend, including a REST API, a database, an SDK, and even an admin panel for non-technical administrators. Manifest lets you focus on your front-end without being slowed down by complex and time-consuming backend tasks. It's perfect for developers who want to ship faster. Here’s an article that describes &lt;a href="https://dev.to/bd_perez/svelte-manifest-giving-svelte-a-proper-backend-with-7-lines-of-code-j6a"&gt;how a developer builds a complete application using Svelte and Manifest&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mnfst/manifest" class="ltag_cta ltag_cta--branded" rel="noopener noreferrer"&gt;Github repository →&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  4. &lt;a href="https://superforms.rocks" rel="noopener noreferrer"&gt;Superforms&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9yppf18yz2bl8wjf8hd2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9yppf18yz2bl8wjf8hd2.png" alt="Superforms website" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://superforms.rocks/" rel="noopener noreferrer"&gt;Superforms&lt;/a&gt; is a form library specifically designed for SvelteKit. It simplifies form management by handling state and real-time validation, making form handling easier in your Svelte applications. Superforms provides a flexible API that integrates seamlessly with SvelteKit routes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ciscoheat/sveltekit-superforms" class="ltag_cta ltag_cta--branded" rel="noopener noreferrer"&gt;Github repository →&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  5. &lt;a href="https://svelte-headlessui.goss.io/docs/2.0" rel="noopener noreferrer"&gt;Svelte Headless UI&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdubl1tgwfux4edf9coga.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdubl1tgwfux4edf9coga.png" alt="Svelte Headless UI website" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://svelte-headlessui.goss.io/docs/2.0" rel="noopener noreferrer"&gt;Svelte Headless UI&lt;/a&gt; is a library of unstyled, accessible UI components, inspired by Tailwind's &lt;a href="https://headlessui.com/" rel="noopener noreferrer"&gt;Headless UI&lt;/a&gt;. It gives you all the interactivity without enforcing styles, allowing you to design the components exactly the way you want. With Svelte’s reactivity and this library's flexibility, building complex UI interactions has never been easier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/rgossiaux/svelte-headlessui" class="ltag_cta ltag_cta--branded" rel="noopener noreferrer"&gt;Github repository →&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  6. &lt;a href="https://layercake.graphics/" rel="noopener noreferrer"&gt;Layer Cake&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzig4eflzf7tvuvv7zqvf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzig4eflzf7tvuvv7zqvf.png" alt="LayerCake website" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://layercake.graphics/" rel="noopener noreferrer"&gt;Layer Cake&lt;/a&gt; is a graphics framework for Svelte developers who want to create charts like those we create with D3.js. Layer Cake is a go-to toolkit for creating scalable, responsive visualizations, whether you're working with maps, bar charts, plots, radars, or other types of charts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mhkeller/layercake" class="ltag_cta ltag_cta--branded" rel="noopener noreferrer"&gt;Github repository →&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  7. &lt;a href="https://hoppscotch.io/" rel="noopener noreferrer"&gt;Hoppscotch&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fld74p5daw1evduir7lx9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fld74p5daw1evduir7lx9.png" alt="Hoppscotch" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hoppscotch.io/" rel="noopener noreferrer"&gt;Hoppscotch&lt;/a&gt; is an open-source API development tool, similar to Postman, but lighter and designed for quick testing and collaboration. While mainly for backend developers, it’s perfect for Svelte front-end devs who need to quickly test APIs, validate responses, and debug integrations—essential for API-driven apps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/hoppscotch/hoppscotch" class="ltag_cta ltag_cta--branded" rel="noopener noreferrer"&gt;Github repository →&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  8. &lt;a href="https://svelte-heros-v2.codewithshin.com/" rel="noopener noreferrer"&gt;Svelte Heros&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F48wm721rrd08odum42bx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F48wm721rrd08odum42bx.png" alt="Svelte Heros" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://svelte-heros-v2.codewithshin.com/" rel="noopener noreferrer"&gt;Svelte Heros&lt;/a&gt; is a collection of free, open-source SVG icons built specifically for Svelte. It’s based on &lt;a href="https://heroicons.com/" rel="noopener noreferrer"&gt;Heroicons&lt;/a&gt; and is incredibly easy to integrate into your Svelte projects. With over 200 icons, Svelte Heros offers easy access to a wide range of icons while keeping your app lightweight and performant.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/shinokada/svelte-heros-v2" class="ltag_cta ltag_cta--branded" rel="noopener noreferrer"&gt;Github repository →&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  9. &lt;a href="https://beartocode.github.io/carta/introduction" rel="noopener noreferrer"&gt;Carta&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxo96jlq1px8y2vj9nbgn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxo96jlq1px8y2vj9nbgn.png" alt="Carta" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://beartocode.github.io/carta/introduction" rel="noopener noreferrer"&gt;Carta&lt;/a&gt; is an efficient and highly adaptable Markdown editor and viewer built for Svelte. It seamlessly integrates with SvelteKit and offers full support for Server Side Rendering (SSR), ensuring flexibility and speed. It comes with a set of essential plugins.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/BearToCode/carta" class="ltag_cta ltag_cta--branded" rel="noopener noreferrer"&gt;Github repository →&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  10. &lt;a href="https://elderguide.com/tech/elderjs/" rel="noopener noreferrer"&gt;Elder.js&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk9du6mkqqkncqacy0ike.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk9du6mkqqkncqacy0ike.png" alt="Elderjs" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://elderguide.com/tech/elderjs/" rel="noopener noreferrer"&gt;Elder.js&lt;/a&gt; is a static site generator focused on SEO for Svelte apps. It offers detailed control over SEO, routing, and data fetching. Optimized for performance, it's ideal for large-scale, fast-loading, SEO-friendly sites.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Elderjs/elderjs" class="ltag_cta ltag_cta--branded" rel="noopener noreferrer"&gt;Github repository →&lt;/a&gt;
&lt;/p&gt;




&lt;p&gt;This collection of tools represents just a glimpse into the vibrant Svelte ecosystem. What sets them apart is their adherence to what makes Svelte itself so powerful - the perfect balance of simplicity and capability. Each tool follows this philosophy, providing robust solutions without unnecessary complexity, helping you build better applications with less cognitive overhead.&lt;/p&gt;

&lt;p&gt;Keep in mind that the Svelte community is constantly innovating - new tools emerge regularly, and existing ones evolve. If you've discovered other gems that share this commitment to elegant, efficient development, feel free to share them in the comments below!&lt;/p&gt;

&lt;p&gt;Happy coding! 🚀&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq8xp2gcqp9wbauqdv8ln.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq8xp2gcqp9wbauqdv8ln.png" alt="Thank you" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>svelte</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How to create a newsletter signup form in just 20 minutes with shadcn/UI and Manifest</title>
      <dc:creator>Sébastien Conejo</dc:creator>
      <pubDate>Tue, 08 Oct 2024 14:56:40 +0000</pubDate>
      <link>https://dev.to/sebconejo/how-to-create-a-newsletter-signup-form-in-just-20-minutes-with-shadcnui-and-manifest-1ile</link>
      <guid>https://dev.to/sebconejo/how-to-create-a-newsletter-signup-form-in-just-20-minutes-with-shadcnui-and-manifest-1ile</guid>
      <description>&lt;p&gt;In today’s digital world, being able to quickly test your ideas and interact with your users is crucial, whether you’re building an MVP, launching a startup, or delivering a project on a tight deadline. Creating a newsletter subscription form is often necessary to validate your concept, engage early users, build a community of interested people, and gather feedback.&lt;/p&gt;

&lt;p&gt;Turnkey solutions can be costly, while using free tools is still complex and time-consuming.&lt;/p&gt;

&lt;p&gt;In this tutorial, I’ll show you how to create a newsletter subscription form in less than 20 minutes. No complex configurations, no headaches. Just a form with a fully functional subscription system!&lt;/p&gt;

&lt;h3&gt;
  
  
  Stack Used
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://ui.shadcn.com/" rel="noopener noreferrer"&gt;shadcn/UI&lt;/a&gt;&lt;/strong&gt;: ready-to-use, beautifully designed components to build the frontend.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://manifest.build" rel="noopener noreferrer"&gt;Manifest&lt;/a&gt;&lt;/strong&gt;: The fastest and easiest way to build a complete backend, just by filling a YAML file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By the end of this tutorial, you’ll have a fully operational form to collect your first subscribers. Ready? Let’s go!&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Manifest?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Manifest&lt;/strong&gt; is our open-source Backend-as-a-Service (BaaS). It allows to create a complete backend for your application. &lt;/p&gt;

&lt;p&gt;By simply filling in a single YAML file, you generate a backend with a database, an API, and a user-friendly admin panel for non-technical administrators.&lt;/p&gt;

&lt;p&gt;This allows you to focus on building your product instead of dealing with backend complexity.&lt;/p&gt;

&lt;p&gt;As of today, we’ve just released our MVP, and we’re counting on community feedback to help us evolve the product in the right direction.&lt;/p&gt;

&lt;p&gt;Manifest is available on &lt;a href="https://github.com/mnfst/manifest" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;, so feel free to give it a ⭐ if you like the project!&lt;/p&gt;

&lt;h2&gt;
  
  
  Planning the interface
&lt;/h2&gt;

&lt;p&gt;Our goal is a single screen displaying a subscription field and notification messages. It's simple, effective, and functional. Here’s what we’ll get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The frontend for subscribers&lt;/li&gt;
&lt;li&gt;The admin panel for the administrators&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Creating the frontend with shadcn/UI
&lt;/h2&gt;

&lt;p&gt;We’ll start by creating the project with the frontend, i.e., the visual part of our newsletter subscription form.&lt;/p&gt;

&lt;p&gt;I chose to use &lt;strong&gt;shadcn/UI&lt;/strong&gt; with Next.js. Run the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx shadcn@latest init -d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll be prompted to start a new Next.js project and name your project. Answer “Y” and call it &lt;code&gt;newsletter-form&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once the project is created, you should have your frontend ready, with these files:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fythehdskyplmxr2hjxl1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fythehdskyplmxr2hjxl1.png" alt="Image description" width="268" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Start the development server by running: &lt;code&gt;npm run dev&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Click on the provided link in the terminal. It should open the NextJS welcome screen in your default web browser at &lt;a href="https://localhost:3000" rel="noopener noreferrer"&gt;https://localhost:3000&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F050dgemryroexzats8x2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F050dgemryroexzats8x2.png" alt="Image description" width="800" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating the static form
&lt;/h3&gt;

&lt;p&gt;Let’s create our form by editing &lt;code&gt;app/page.tsx&lt;/code&gt;. Since shadcn works with &lt;a href="https://tailwindcss.com/docs/" rel="noopener noreferrer"&gt;TailwindCSS&lt;/a&gt;, we’ll use its classes to build the desired interface. Copy the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;w-full lg:grid lg:grid-cols-5 min-h-screen flex sm:items-center sm:justify-center sm:grid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex items-center justify-center py-12 col-span-2 px-8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mx-auto grid max-w-[540px] gap-6&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;grid gap-2 text-left&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-3xl font-bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Subscribe&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;our&lt;/span&gt; &lt;span class="nx"&gt;Newsletter&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="err"&gt;💌&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-balance text-muted-foreground&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="nx"&gt;Get&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;latest&lt;/span&gt; &lt;span class="nx"&gt;news&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;updates&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;special&lt;/span&gt; &lt;span class="nx"&gt;offers&lt;/span&gt; &lt;span class="nx"&gt;delivered&lt;/span&gt; &lt;span class="nx"&gt;straight&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;your&lt;/span&gt; &lt;span class="nx"&gt;inbox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;grid gap-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Newsletter form here */&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/form&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hidden bg-muted lg:block col-span-3 min-h-screen bg-gradient-to-t from-green-50 via-pink-100 to-purple-100&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see a split screen with an area for the form on the left and a gradient space on the right.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw83nuq9hwercg7m89tte.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw83nuq9hwercg7m89tte.png" alt="Image description" width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let’s add the form. It will include the following shadcn components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Input&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Button&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Install these components via your terminal with the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx shadcn@latest add input
npx shadcn@latest add button
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then import the components in your &lt;code&gt;page.tsx&lt;/code&gt; file like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/components/ui/button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Input&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/components/ui/input&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use these two components by adding the following snippet inside the existing &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;grid gap-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex w-full max-w-sm items-center space-x-2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Input&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Subscribe&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-sm text-muted-foreground&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;Sent&lt;/span&gt; &lt;span class="nx"&gt;out&lt;/span&gt; &lt;span class="nx"&gt;weekly&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="nx"&gt;Mondays&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Always&lt;/span&gt; &lt;span class="nx"&gt;free&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/form&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should have a responsive newsletter form on your frontend. Take a moment to admire your work. And relax, our 20-minute promise is still intact!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F76xia1clsonsiqlyhu9y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F76xia1clsonsiqlyhu9y.png" alt="Image description" width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the backend with Manifest
&lt;/h2&gt;

&lt;p&gt;Let’s add the backend to store the subscribers and allow administrators to manage them via an admin panel. &lt;/p&gt;

&lt;p&gt;Install Manifest at the root of the project with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx add-manifest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the backend is installed, you should see the following files in your repository:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyjtq2wqew3xrdrytmjtw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyjtq2wqew3xrdrytmjtw.png" alt="Image description" width="258" height="68"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let’s define our data model. Open the &lt;code&gt;backend.yml&lt;/code&gt; file and replace the existing code with this one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Newsletter&lt;/span&gt; &lt;span class="nx"&gt;Form&lt;/span&gt;

&lt;span class="nx"&gt;entities&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nx"&gt;Subscriber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the following command to start your server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run manifest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once your backend is running, the terminal will provide two links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🖥️ Admin panel : &lt;a href="http://localhost:1111" rel="noopener noreferrer"&gt;http://localhost:1111&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;📚 API Doc: &lt;a href="http://localhost:1111/api" rel="noopener noreferrer"&gt;http://localhost:1111/api&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Launch the admin panel on your browser and log in with the pre-filled credentials. You should now see an empty list of subscribers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd4cbry6nsh8xxxeq2v4f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd4cbry6nsh8xxxeq2v4f.png" alt="Image description" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There we have it! In under 3 minutes, We’ve built a full backend for our newsletter subscription form. 💪&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting Manifest with our frontend
&lt;/h2&gt;

&lt;p&gt;We’ll use Manifest’s SDK to connect the form and add emails directly to the &lt;code&gt;subscribers&lt;/code&gt; list from the frontend.&lt;/p&gt;

&lt;p&gt;From your project’s root, install the SDK with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i @mnfst/sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s add the newsletter subscription functionality to turn the static form into a dynamic one that stores emails using Manifest.&lt;/p&gt;

&lt;p&gt;Next.js treats the files in the &lt;code&gt;app&lt;/code&gt; directory as &lt;strong&gt;Server Components&lt;/strong&gt; by default. To use interactive features (like React hooks), we need to mark our component as a &lt;strong&gt;Client Component&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Add &lt;code&gt;"use client";&lt;/code&gt; at the top of your &lt;code&gt;Home.tsx&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, create the &lt;code&gt;handleSubmit&lt;/code&gt; function to capture the email and send it to Manifest:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FormEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLFormElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentTarget&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;HTMLFormElement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;emailInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input[name="email"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;HTMLInputElement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;emailInput&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Please enter a valid email.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;manifest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Manifest&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;manifest&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;subscribers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Successfully subscribed!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error adding subscriber:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Failed to add subscriber: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="c1"&gt;// ... Your existing code here&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, add the &lt;code&gt;onSubmit={handleSubmit}&lt;/code&gt; attribute to your &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;onSubmit=&lt;/span&gt;&lt;span class="s"&gt;{handleSubmit}&lt;/span&gt; &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;"grid gap-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Testing the form
&lt;/h3&gt;

&lt;p&gt;Time to see our form in action! Enter an email address and hit submit. You should get a confirmation message. &lt;/p&gt;

&lt;p&gt;Check the admin panel, and voilà! this email is now in the subscriber list!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc3tfxplgg6xp4w63aopg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc3tfxplgg6xp4w63aopg.png" alt="Image description" width="800" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Enhancing user experience
&lt;/h3&gt;

&lt;p&gt;Let’s add alerts to indicate whether the subscription was successful or not. We’ll use the ShadUI alert component.&lt;/p&gt;

&lt;p&gt;Install the alert component with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx shadcn@latest add alert
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now add the alert function, and integrate it into our form. Here is the final &lt;code&gt;page.tsx&lt;/code&gt; page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Alert&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;AlertDescription&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/components/ui/alert&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/components/ui/button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Input&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/components/ui/input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Manifest&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@mnfst/sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;alertVisible&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setAlertVisible&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// State to manage alert visibility&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;alertMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setAlertMessage&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Message to display in the alert&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FormEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLFormElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;// Retrieve email from the input field&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentTarget&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;HTMLFormElement&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;emailInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input[name="email"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;HTMLInputElement&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;emailInput&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setAlertMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Please enter a valid email.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nf"&gt;setAlertVisible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setAlertVisible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Hide the alert after 3 seconds&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;manifest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Manifest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;manifest&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;subscribers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Reset the email input field after success&lt;/span&gt;
        &lt;span class="nf"&gt;setAlertMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Successfully subscribed! We will contact you if you are selected.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;setAlertVisible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Show success alert&lt;/span&gt;
        &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setAlertVisible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Hide the alert after 3 seconds&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;setAlertMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Failed to add subscriber: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;setAlertVisible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Show error alert&lt;/span&gt;
        &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setAlertVisible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Hide the alert after 3 seconds&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;w-full lg:grid lg:grid-cols-5 min-h-screen flex sm:items-center sm:justify-center sm:grid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex items-center justify-center py-12 col-span-2 px-8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;relative mx-auto grid max-w-[540px] gap-6&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;grid gap-2 text-left&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-3xl font-bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="nx"&gt;Subscribe&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;our&lt;/span&gt; &lt;span class="nx"&gt;Newsletter&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="err"&gt;💌&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-balance text-muted-foreground&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="nx"&gt;Get&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;latest&lt;/span&gt; &lt;span class="nx"&gt;news&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;updates&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;special&lt;/span&gt; &lt;span class="nx"&gt;offers&lt;/span&gt; &lt;span class="nx"&gt;delivered&lt;/span&gt;
              &lt;span class="nx"&gt;straight&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;your&lt;/span&gt; &lt;span class="nx"&gt;inbox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleSubmit&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;grid gap-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex w-full max-w-sm items-center space-x-2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Input&lt;/span&gt;
                &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;m@example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;required&lt;/span&gt;
              &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Subscribe&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-sm text-muted-foreground&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="nx"&gt;Sent&lt;/span&gt; &lt;span class="nx"&gt;out&lt;/span&gt; &lt;span class="nx"&gt;weekly&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="nx"&gt;Mondays&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Always&lt;/span&gt; &lt;span class="nx"&gt;free&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/form&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Display the alert based on alertVisible state */&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;alertVisible&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Alert&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;absolute bottom-[-90px] bg-teal-300 border-teal-400 text-teal-800&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AlertDescription&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;alertMessage&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/AlertDescription&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Alert&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="p"&gt;)}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hidden bg-muted lg:block col-span-3 min-h-screen bg-gradient-to-t from-green-50 via-pink-100 to-purple-100&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's try the form with the alert by entering a new valid email.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffby0kojgihetnlenzeoj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffby0kojgihetnlenzeoj.png" alt="Image description" width="800" height="529"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! 🎉 You’ve just built a fully functional newsletter subscription application in a flash! ⚡&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;By leveraging Manifest alongside your favorite frontend tools, you can rapidly create applications with minimal effort. Manifest has been instrumental in speeding up our development process, allowing us to set up a complete backend in just minutes.&lt;/p&gt;

&lt;p&gt;I hope this guide was helpful and that you learned how to create a simple and effective newsletter subscription system for your future projects.&lt;/p&gt;

&lt;p&gt;If you'd like to access the full project code, you can check out the repository &lt;a href="https://github.com/SebConejo/newsletter-form" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you liked using Manifest, consider giving us a ⭐ on &lt;a href="https://github.com/mnfst/manifest" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; to support the project and stay updated!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>tutorial</category>
      <category>opensource</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
