From 1cba33bb417c43d243b3da8dae10d1060e797ea8 Mon Sep 17 00:00:00 2001 From: Zach Plata Date: Thu, 26 Jun 2025 09:38:00 -0500 Subject: [PATCH] Update README --- README.md | 177 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 101 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index 5a9347a..9440d22 100644 --- a/README.md +++ b/README.md @@ -1,99 +1,116 @@ -# Serving Assets Under a Custom Domain with Webflow Cloud +# Asset Routing with Webflow Cloud -[Webflow Cloud](https://webflow.com/cloud) enables you to deploy full-stack web applications directly under your Webflow-hosted domain. It can also be leveraged to serve assets from the same domain, which is especially useful for scenarios where assets must reside under the primary domain rather than Webflow’s default asset CDN path. Below is an overview of how to set this up, along with key considerations. +A Webflow Cloud example app demonstrating how to serve static assets directly under your Webflow-hosted domain. Built with Next.js, this app showcases asset routing techniques for scenarios where assets must reside under the primary domain rather than Webflow's default CDN path. -Example live paths: +## ✨ Features + +- **Custom Asset Hosting**: Serve static assets directly under your Webflow domain +- **Flexible File Organization**: Support for nested folder structures in the public directory +- **API Route Implementation**: Custom Next.js API routes for secure file serving +- **Multiple File Type Support**: Handle images, documents, and other static assets + +## 💡 Why Serve Assets Under Your Domain? + +By default, Webflow hosts assets (e.g., images, documents, etc) via a standardized CDN URL (`cdn.prod.website-files.com/...`). However, certain use cases may require that assets be accessible directly under the custom domain (e.g., `https://yourdomain.com/assets/image.png`). Additionally, you can retain SEO benefits by serving assets all from the same domain rather than various external sources. + +Webflow Cloud enables this with a structured approach using Next.js's `public` folder + API routing. + +**Note:** _If you are still able to serve files directly from the public folder, this behavior may change in the future. Direct access to the public directory could be disabled, and using an API route will be required._ + +## 🛠️ Tech Stack + +- **Webflow Cloud** - Infrastructure for hosting the webapp alongside a Webflow site +- **Next.js** - Webapp framework with API routing capabilities + +## 📋 Prerequisites + +Make sure you have the following before running the app locally: + +- Install Node.js 18+ / npm / Git +- Webflow account (sign up for free) and site created +- Install the [Webflow CLI](https://www.npmjs.com/package/@webflow/webflow-cli) + +## 🏗️ Getting Started + +### 1. Fork and clone the repository + +- Fork this repo into your own repositories so you have a copy of this project to work with +- Clone the repo down to your local machine +- `cd asset-routing-webflow-cloud` + +### 2. Install and run locally + +```bash +npm install +npm run dev +``` + +### 3. (Optional) Add your assets + +Place any additional static assets in the `public` directory. You can organize them with the current subfolder structure: + +- `/public/photo.png` → accessible at `/assets/photo.png` +- `/public/images/logo.png` → accessible at `/assets/images/logo.png` +- `/public/files/whitepaper.pdf` → accessible at `/assets/files/whitepaper.pdf` + +**Note:** _`/assets` is the mount path for the Webflow Cloud app and is required. You will have the option to customize this mount path when creating the Webflow Cloud app. See [Webflow Cloud docs](https://developers.webflow.com/webflow-cloud/intro)._ + +### 4. Test asset serving + +The development server will start and you can test asset access at: + +- `http://localhost:3000/assets/[your-file-name]` + +**Example localhost paths:** + +- http://localhost:3000/assets/bird.jpg +- http://localhost:3000/assets/images/forest.jpg + +**Example live paths:** - https://wf-cloud-test-5650e8.webflow.io/assets/bird.jpg - https://wf-cloud-test-5650e8.webflow.io/assets/images/forest.jpg ---- +## 🚀 Deploy Webflow Cloud app -## Why Serve Assets Under Your Domain? +Once everything locally works OK, it's time to build and deploy the Webflow Cloud app to your Webflow site at the mounted path. -By default, Webflow hosts assets (e.g., images, documents, etc) via a standardized CDN URL (`cdn.prod.website-files.com/...`). However, certain use cases may require that assets be accessible directly under the custom domain (e.g., `https://yourdomain.com/assets/image.png`). +First, push up any code changes made to the project to the forked remote GitHub repo. -Webflow Cloud enables this with a structured approach using Next.js’s/Astro's `public` folder + API routing. +### Create Webflow Cloud app -**Note:** _If you are still able to serve files directly from the public folder, this behavior may change in the future. Direct access to the public directory could be disabled, and using an API route will be required._ +> For more detailed guidance on creating a Webflow Cloud app, see [docs here](https://developers.webflow.com/webflow-cloud/intro) for a step-by-step. ---- +In your Webflow site settings, navigate to the **Webflow Cloud** tab, click "Install GitHub App", and follow the prompts so Webflow can access your forked repo. -## Implementation Overview +Back in the Webflow Cloud page, click the "Create New Project" button and follow the prompts accordingly to add your project name, and the location of your GitHub repo. -### 1. Place Assets in the `public` Folder in Next JS/Astro +When you are prompted to create an **Environment**: -Add your static assets (images, documents, etc.) into the `public` directory of your Next.js project. You can organize them with subfolders or have them at the root like: +1. **Branch** - Select the GitHub branch you're working from (usually `main`) +2. **Mount Path** - Enter `/assets` -- `/public/photo.png` -- `/public/images/logo.png` -- `/public/files/whitepaper.pdf` +After the project is created, click "Publish" to re-publish your Webflow site. Once publishing completes, open your Webflow Cloud project, navigate into the **Environments**, then select the `main` branch name to view **Deployments**. -This structure allows access via routes like: +### Deploy the app -- `/assets/photo.png` -- `/assets/images/logo.png` -- `/assets/files/whitepaper.pdf` +Click the "Deploy latest commit" button to build and deploy the latest app from your repo. -**Note:** _`/assets` is the mount path for the Webflow Cloud app and is required. You will have the option to customize this mount path when creating the Webflow Cloud app. See [Webflow Cloud docs](https://developers.webflow.com/webflow-cloud/intro)._ +After a few minutes, you can click the "Environment URL", which should be where the app is deployed to on your site (i.e. `https://{your-site-here}.webflow.io/assets/bird.jpg`). -### 2. Create an API Route to Serve Files +If you can access your assets at the expected URLs, congrats! You've deployed your first Webflow Cloud asset routing app 🎉 -To serve files from the `public` folder, implement a custom API route like this: +If you make additional changes to your project, simply push them up to your repo on `main`, and Webflow will automatically kick off a new deployment with your changes. Also, if your deployment build fails for any reason, check the "Deployment History" for more logs. -```js -// route.js - -// Import necessary Next.js server components and utilities -import { NextRequest, NextResponse } from "next/server"; -// Import path module for handling file paths -import path from "path"; -// Import file system promises API for async file operations -import { promises as fs } from "fs"; -// Import mime-types for determining content type of files -import mime from "mime-types"; - -// Define GET handler for serving static assets -export async function GET(request: NextRequest) { - // Parse the request URL to extract the path - const url = new URL(request.url); - // Remove '/assets/' prefix and split remaining path into segments - const slug = url.pathname.replace(/^\/assets\//, "").split("/"); - - // Construct the full file path by joining current working directory, 'public' folder, and slug segments - const filePath = path.join(process.cwd(), "public", ...slug); - - try { - // Read the file as a buffer - const fileBuffer = await fs.readFile(filePath); - // Determine the content type based on file extension, fallback to octet-stream - const contentType = mime.lookup(filePath) || "application/octet-stream"; - - // Return the file with appropriate headers - return new NextResponse(fileBuffer, { - status: 200, - headers: { - "Content-Type": contentType, - }, - }); - } catch (err: any) { - // Handle file not found or other errors - return new NextResponse( - JSON.stringify({ - error: "File was not found", - }), - { - status: 404, - headers: { "Content-Type": "application/json" }, - } - ); - } -} -``` +## 🔧 Implementation Details + +### API Route for File Serving + +To serve files from the `public` folder, see the `[...slug]/route.ts` [file here](src/app/[...slug]/route.ts). **Note:** _For security purposes, it's not possible to set your own cache control headers (they will be overridden)._ -## Using Hosted Assets in the Webflow Designer +## 🎨 Using Hosted Assets in the Webflow Designer To use these custom-hosted assets inside the Webflow Designer, use the [Custom Element](https://help.webflow.com/hc/en-us/articles/33961250668691-Custom-element). @@ -103,9 +120,9 @@ For example, use the `` tag and reference the hosted asset with the src att **Note:** _Use the loading attribute for performance optimization. For example, loading="lazy" for below-the-fold images and loading="eager" for above-the-fold content like hero banners._ -## Limitations of This Approach +## ⚠️ Limitations of This Approach -While this method provides flexibility, do not rely on it as your primary asset management strategy. Limitations include: +While this strategy provides flexibility, we do not recommend relying on it as your primary asset management strategy. Limitations include: - No responsive variants - No native compression options i.e., convert JPG/PNG to WEBP/AVIF @@ -114,7 +131,7 @@ While this method provides flexibility, do not rely on it as your primary asset For most use cases, Webflow's built-in [Asset Panel](https://help.webflow.com/hc/en-us/articles/33961269934227-Assets-panel) should be the preferred choice. -## Optional: Redirect Unused Paths +## 🔄 Optional: Redirect Unused Paths If your Webflow Cloud project is only used to serve assets, consider redirecting the root or other unused paths back to the main Webflow site and prevent users from landing on empty or incorrect pages. @@ -127,7 +144,7 @@ This can be done by defining a page like... import { redirect } from "next/navigation"; export default function AssetsRootRedirect() { - redirect("https://wf-cloud-test-5650e8.webflow.io"); + redirect("https://your-webflow-site.webflow.io"); } ``` @@ -151,3 +168,11 @@ module.exports = { }, }; ``` + +## 🤝 Contributing + +Feel free to submit issues and pull requests! + +## 📄 License + +This project is MIT licensed.