Back in May 2016, we created a micro-website called Tour de France Eire for the honorary consul of the French Embassy in Galway, Catherine Gagneux. The site mapped French businesses across the Republic of Ireland, displaying their information to help potential customers discover them and connect the French community of Ireland with local services. To support growth over time, we added self-service registration for businesses and an approval dashboard for the Consul’s team to curate listings.

After years of service, we decided to revamp the site with newer technologies and a cleaner, modern design. In the age of AI-assisted development, our processes have evolved. We integrate AI tools where they genuinely improve efficiency without compromising quality. When we kicked off this upgrade, time constraints were significant, so we turned to Figma Make to accelerate the initial build.

In this article, we will explore our journey rebuilding Tour de France Eire, examining the limitations of AI code generation tools like Figma Make, and sharing the practical solutions we developed to create a production-ready workflow that bridges design iteration with API integration and SEO requirements.

Getting started with Figma Make

We used Figma Make to jump-start the new version. For those unfamiliar with the tool, Figma Make accepts a text prompt and generates a web application using React and Tailwind CSS, with Radix UI providing accessible UI primitives.

Create AI Designs using Figma Make

The output is visually polished and well-structured, but a React application is not automatically a production-ready website. Real websites need working features, connected data sources, and search engine visibility. Out of the box, Figma Make provides no database integration, some interactions require debugging, and client-side rendering leaves search engine crawlers with minimal indexable content. This is expected behavior for any code generation tool. The challenge lies in transforming a promising export into a reliable, maintainable website while preserving the ability to iterate on design through future Figma regenerations.

Managing design-to-code drift

As soon as you modify generated code, you diverge from the source. Future design iterations in Figma Make will export fresh code that no longer matches your production implementation. Without a strategy to manage this drift, you face the tedious task of manually identifying and re-applying every custom change with each regeneration.

We employ two strategies to address this. First, we leverage Figma Make’s GitHub integration to track changes and simplify code synchronization. Second, and more importantly, we instruct Figma Make during the initial prompt to abstract all data-handling functions into a centralized state management layer. This architectural separation between presentation and business logic is a well-established best practice that becomes critical when working with generated code.

In practice, this means components receive props and render UI without containing data fetching or mutation logic. A separate data layer handles all reads and writes through React Context, a lightweight state store, or server actions. When you regenerate UI components from Figma Make, the data layer remains untouched, localizing changes to the presentation layer. Diffs become predictable, and merging intentional design changes becomes straightforward. We also commit each raw Figma Make export as its own commit, keeping diffs readable and making it easy to identify what changed between iterations.

Example of a DataLayer Architecture

Solving the SEO challenge

Search engine optimization presents a more complex challenge. To understand why, we need to examine how React applications work. React is a client-side framework that delivers a minimal HTML shell to the browser, then executes JavaScript to render content. This approach offers excellent performance for interactive applications, but creates problems for search engine crawlers.

When a React application loads, the initial HTML is essentially empty. Content appears only after JavaScript executes and the first render completes. While this provides a smooth user experience, search engine crawlers scanning the page see an empty document. They can index metadata in the <head> element like meta tags and Open Graph properties, but miss all body content, severely limiting discoverability.

If you are building an application that does not require search engine visibility — such as authenticated tools or internal dashboards — client-side rendering is perfectly acceptable. However, if search visibility matters, you need server-side rendering or static site generation. React alone does not provide this capability. Next.js, a production-grade React framework, does.

For public pages, we configure Next.js to render on the server, ensuring crawlers receive fully-populated HTML. We also implement unique titles and descriptions for each page, add canonical URLs to prevent duplicate content issues, and generate a sitemap and robots.txt. To verify this works, you can fetch a page as a crawler would and confirm the content appears in the raw HTML:

curl -s <https://example.com> | sed -n '1,80p'

If your application is private or requires authentication, client-side rendering is sufficient. If you need search visibility, server-side rendering or static generation is non-negotiable.

For teams without React experience, implementing this fix can be challenging. In that case, consider platforms that generate full-stack applications with built-in SEO support, database connectivity, and server-side rendering. Options include Base44, v0 Emergent, Blink, Bolt, and Replit.

The Next.js Framework

Migrating Figma Make output to Next.js

For developers comfortable with React, migrating Figma Make output to Next.js is straightforward. Figma Make provides a components/ directory with all UI building blocks, an assets/ directory with images and CSS, and page composition in App.tsx. Since Figma Make uses Tailwind CSS and Radix UI, both of which integrate seamlessly with Next.js, the migration is primarily a matter of reorganization.

We began by aligning React and Next.js versions to ensure compatibility. Then we copied components and assets into our Next.js project structure and translated the routing logic in App.tsx into Next.js routes within the app/ or pages/ directory, depending on which Next.js router version you are using.

Next, we installed Figma Make’s dependencies, taking care to match React versions with Next.js requirements. This sometimes requires manual version alignment to avoid compatibility issues.

Following our earlier architectural advice, Figma Make should have generated a store/ or hooks/ directory containing data-handling functions with mock data and placeholder state management. We replaced this entirely with our API and database implementation, connecting to real data sources and implementing actual write operations.

We also needed authentication, which we prompted Figma Make to include in the initial generation. This provided a login page with state management hooks in the data layer. We replaced the mock authentication logic with our production authentication system. The result appears identical to users but now renders on the server, connects to live data, and indexes properly in search engines.

Ensuring accessibility and UI quality

Generated interfaces often look correct but lack the accessibility and interaction details that matter in production. We audited and corrected several common issues: ensuring interactive elements use semantic HTML like links and buttons rather than generic containers with click handlers, managing focus correctly during route transitions and within modal dialogs, maintaining visible focus indicators for keyboard navigation, verifying color contrast ratios meet WCAG standards, and adding proper labels to form inputs and meaningful alt text to images.

Accessibility, UI Quality & WCAG standards

These are small, predictable fixes that significantly improve usability for all visitors, particularly those using assistive technologies. To prevent regressions, we integrated lightweight accessibility checks using axe and automated interaction tests with Playwright into our testing pipeline.

Optimizing performance and maintainability

We took several steps to ensure the application performs well and remains maintainable as it grows. We minimized hydration overhead by preferring server components where appropriate, implemented code splitting for heavier sections to reduce initial bundle size, used responsive images with lazy loading, removed unused dependencies to keep the bundle lean, and integrated Lighthouse checks into our CI pipeline to catch performance regressions early.

Our goal is straightforward: fast initial page load, responsive interactions, and a codebase that remains easy to understand and evolve.

Measure performance and maintainability for better results

Strategies for sustainable regeneration

We learned to set clear expectations with Figma Make during the initial prompt: keep business logic out of UI components and maintain stable component props. This makes future regenerations significantly easier to integrate. When design updates are needed, we regenerate by section rather than exporting the entire application at once. This contains changes to specific areas and simplifies code review.

We also maintain a brief README documenting intentional post-generation changes, with entries like “replaced mock authentication in store/auth.ts with Firebase" or "added SEO metadata to all public routes." This record serves as a reference during future iterations, making it clear which modifications to preserve rather than having to rediscover customizations through trial and error.

Establishing an efficient team workflow

In practice, we treat Figma Make exports as upstream dependencies. Before generating updated code, we commit all current work. We isolate each Figma Make export in its own pull request, keeping diffs clean and making rollbacks simple if issues arise. This approach preserves development velocity, maintains control over what reaches production, and makes integrating future design changes straightforward without losing production-ready features we have implemented.

This workflow allowed us to leverage Figma Make’s speed while building production-ready features incrementally. Most importantly, it enables continued design iteration in Figma while the application evolves into a robust Next.js implementation with live data, accessible interactions, and functional SEO.

Conclusion

Figma Make provides speed and a solid visual foundation for rapid prototyping. Production readiness requires several deliberate architectural decisions: separate presentation from business logic with a clear data layer to make regeneration manageable, render public pages server-side with Next.js to ensure search visibility, verify accessibility through consistent automated checks, and protect performance with guardrails in your CI pipeline. Treat each Figma Make export as an upstream dependency, regenerate incrementally by section when design changes are needed, and document only the intentional modifications you make to the generated code.

Following this approach, you can continue iterating designs in Figma while your application matures into a maintainable Next.js codebase that is crawlable by search engines, accessible to all users, performant, and straightforward to evolve.

If this article was helpful, or have any questions, please leave a comment, it will be a pleasure to help!


From Figma Make to production in a day was originally published in Creative by Black Pug Studio on Medium, where people are continuing the conversation by highlighting and responding to this story.