New Project
Open-source Astro website template with sleek, customizable TailwindCSS components.

ScrewFast is an open-source website template built with Astro, Tailwind CSS, and Preline UI. You get a landing page, blog, product pages, and a full documentation site in one repo, so you can launch a complete web presence by editing content and props instead of building pages from scratch. Unlike single-purpose landing or blog themes, it ships with SEO metadata, i18n, security headers, and CI already wired up.
Live demo: screwfast.uk
robots.txt.vercel.json, post-build HTML minification, and a CI pipeline that type-checks, builds, and smoke-tests every push.AI_GUIDE.md tells Cursor, Copilot, and Claude where things live and which conventions to follow.Pages are composed from sections with plain props:
---import MainLayout from '@/layouts/MainLayout.astro';import HeroSection from '@components/sections/landing/HeroSection.astro';---<MainLayout title="Acme Tools"><HeroSectiontitle="Equip Your Projects with Acme"subTitle="Top-quality hardware tools for every project need."primaryBtn="Start Exploring"primaryBtnURL="/products"/></MainLayout><!-- Renders a full page with navbar, hero, and footer -->
You need Node.js 22 and pnpm 9 or newer (the versions CI uses).
1. Create your repo. Click Use this template at the top of the GitHub page, or clone directly:
git clone https://github.com/mearashadowfax/ScrewFast.git my-sitecd my-site
2. Install dependencies:
pnpm install
3. Start the dev server:
pnpm dev
Open http://localhost:4321. Edits to any file reload the page.
4. Build for production:
pnpm build
This runs astro check (type-checking), builds the site into dist/, and minifies the HTML. Preview the result with pnpm preview, or run pnpm test:smoke to serve dist/ and verify the key routes respond.
[!TIP] Only need one language? The
monolingual-sitebranch has the French pages and i18n plumbing removed.
Everything site-wide lives in src/data_files/constants.ts:
export const SITE = {title: 'ScrewFast',tagline: 'Top-quality Hardware Tools',description: '...',url: 'https://screwfast.uk',author: 'Emil Gulamov',};export const SEO = { title: SITE.title, description: SITE.description, structuredData: { ... } };export const OG = { locale: 'en_US', type: 'website', title: `${SITE.title}: ...`, image: ogImageSrc, ... };
Change SITE, and the <Meta> component picks it up on every page. Also update site in astro.config.mjs so the sitemap and robots.txt point at your domain.
Edit src/utils/navigation.ts (and src/utils/fr/navigation.ts for French):
const navBarLinks = [{ name: 'Home', url: '/' },{ name: 'Products', url: '/products' },{ name: 'Blog', url: '/blog' },];const footerLinks = [{ section: 'Ecosystem', links: [{ name: 'Documentation', url: '/welcome-to-docs/' }] },{ section: 'Company', links: [{ name: 'About us', url: '#' }] },];const socialLinks = { facebook: '#', x: '#', github: '#', ... };
Two navbars are included in src/components/sections/navbar&footer/: Navbar.astro (standard) and NavbarMegaMenu.astro (mega menu, links in src/data_files/mega_link.ts). Swap them in src/layouts/MainLayout.astro.
Pages in src/pages/ compose sections from src/components/sections/ and pass content as props, exactly like the example above. Open src/pages/index.astro to see the full homepage, then edit the props or remove sections you don't need.
Sections take all their copy as props, so page files are the single place to edit text. Reusable data such as FAQs, features, and pricing tiers lives as JSON in src/data_files/ and is passed in the same way.
Content is Markdown/MDX in src/content/{blog,products,insights}/{en,fr}/. Schemas are defined in src/content.config.ts. A blog post looks like:
---title: "Maximizing Efficiency with ScrewFast's Cutting-Edge Tools"description: 'Innovating Construction Efficiency with Precision Tools & Support'author: 'Jacob'authorImage: '@/images/blog/jacob.avif'pubDate: 2024-02-06cardImage: '@/images/blog/post-1.avif'readTime: 4tags: ['tools', 'construction', 'workflow']---Post body here.
Blog posts get social share buttons, a localStorage bookmark button, and a feedback widget (UI only, no back end). Insight pages get a table of contents with a scroll-progress indicator.
Docs live in src/content/docs/ and are served by Starlight at /welcome-to-docs/. Sidebar, locales, and custom components are configured in the starlight() block of astro.config.mjs. Starlight brings search, dark mode, code highlighting, and responsive navigation.
[!IMPORTANT] If the docs sidebar won't scroll, remove the Lenis
<script>fromsrc/components/ui/starlight/Head.astro.
Marketing pages are file-based: src/pages/ for English, src/pages/fr/ for French. A LanguagePicker component switches between them. Use getMarketingLocale() from src/utils/locale.ts when you need the current locale in a component. Docs locales are configured in Starlight; guides and the welcome page are translated, other docs sections fall back to English.
SVG icons are centralized in src/components/ui/icons/icons.ts (38 included). Render one with:
<Icon name="tools" />
Add an entry to icons.ts to register a new icon.
pnpm build produces a static site in dist/ that any static host can serve.
vercel.json adds security headers and caching rules.src/├── assets/│ ├── scripts/ # Lenis smooth scroll, demo form handlers│ └── styles/ # global.css, lenis.css, Starlight overrides├── components/│ ├── Meta.astro # SEO, Open Graph, JSON-LD│ ├── ThemeIcon.astro # Light/dark toggle│ ├── sections/ # Page sections: landing, features, pricing, navbar&footer, ...│ └── ui/ # Buttons, cards, forms, icons, banners, ...├── content/│ ├── blog/ products/ insights/ # en/ and fr/ subfolders│ └── docs/ # Starlight docs + translated locales├── data_files/ # constants.ts (SITE/SEO/OG), faqs.json, features.json, pricing.json├── images/ # Imported and optimized by Astro├── layouts/│ └── MainLayout.astro # Navbar + slot + footer, Meta, Lenis, Preline├── pages/ # File-based routes; fr/ for French│ ├── index.astro blog/ products/ insights/ contact.astro services.astro│ ├── 404.astro│ └── robots.txt.ts manifest.json.ts favicon.ico.ts├── utils/ # navigation.ts, locale.ts, helpers└── content.config.ts # Content collection schemaspublic/ # Served as-isprocess-html.mjs # Post-build HTML minifierscripts/smoke.mjs # Serves dist/ and checks key routesvercel.json # Security headers and cachingAI_GUIDE.md # Conventions for AI coding assistants
Path aliases (@components/*, @data/*, @images/*, @scripts/*, @styles/*, @utils/*, @/*) are defined in tsconfig.json.
Lenis is loaded from src/assets/scripts/lenisSmoothScroll.js in MainLayout.astro and in src/components/ui/starlight/Head.astro. Smooth scrolling can affect accessibility and performance on some devices, so test it with your audience.
To go back to native scrolling, delete this from both files:
<script>import '@scripts/lenisSmoothScroll.js';</script>
GSAP animates product and insight detail pages on load. The setup is in the <script> blocks of src/components/sections/products/ProductDetail.astro and src/components/sections/insights/InsightDetail.astro. Tweak the gsap.from() calls, or delete the script blocks to drop GSAP.
The scrollbar is hidden for a cleaner look. This can hurt usability for some users; to restore it, remove the scrollbar-hide class from <html> in MainLayout.astro and delete the .scrollbar-hide styles at the bottom of that file. For styled scrollbars, tailwind-scrollbar is a good fit.
MainLayout passes title, meta, structuredData, customDescription, and customOgTitle to Meta.astro, falling back to constants.ts when a page doesn't override them:
---import { SITE } from '@data/constants';---<MainLayouttitle={`Example Page | ${SITE.title}`}structuredData={{'@context': 'https://schema.org','@type': 'WebPage',name: 'Example Page',url: `${SITE.url}/example`,}}>...</MainLayout>
Add more tags to Meta.astro (article dates, Twitter-specific fields) if you need them, or swap in an integration like astro-seo.
src/pages/robots.txt.ts generates robots.txt at build time and links to the sitemap produced by @astrojs/sitemap. Both derive the domain from site in astro.config.mjs.
@astrojs/mdx is enabled, so content files can be .md or .mdx. The included .vscode/settings.json lets you paste or drag an image into a content file while holding Shift: VS Code copies it to src/images/content/<file-name>/ and inserts the Markdown link.
pnpm build finishes by running process-html.mjs, which minifies every HTML file in the build output with html-minifier-terser.
vercel.json sets Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, and caching headers. Adjust the CSP if you add third-party scripts or image hosts.
Prettier with prettier-plugin-astro and prettier-plugin-tailwindcss (class sorting) is configured in .prettierrc. Run pnpm format:fix locally; CI runs pnpm format:check.
pnpm format:fix and pnpm build before submitting.See CODE_OF_CONDUCT.md.
MIT. See LICENSE.
The company, products, and logos shown are fictional or used for demonstration only and should be replaced in your site.