Edge Functions for Website (Cloudflare Workers)

Our company is engaged in the development, support and maintenance of sites of any complexity. From simple one-page sites to large-scale cluster systems built on micro services. Experience of developers is confirmed by certificates from vendors.
Development and maintenance of all types of websites:
Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1212
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    852
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    822
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    815

Edge Functions Development for Websites (Cloudflare Workers)

Cloudflare Workers are edge functions running on 300+ Cloudflare PoP nodes. Unlike Vercel Edge, Workers run on your domain as part of the CDN: every HTTP request to yourdomain.com can be intercepted, modified, or fully handled by a Worker without hitting the origin server.

Architectural Patterns

Workers as API Gateway — Worker receives requests, performs authentication, rate limiting, routing, and proxies to the right backend.

Workers as Middleware — modify requests/responses: add headers, transform body, redirect by geolocation.

Workers as full API — complete logic in Worker with storage in KV/D1/R2. Origin server not needed.

Example: Rate Limiting and Authentication

import { Hono } from "hono";
import { jwt } from "hono/jwt";

const app = new Hono<{ Bindings: Env }>();

// Rate limiting via KV
app.use("*", async (c, next) => {
  const ip = c.req.header("CF-Connecting-IP") || "unknown";
  const key = `rate:${ip}`;

  const count = parseInt(await c.env.KV.get(key) || "0");

  if (count > 100) {
    return c.json({ error: "Too many requests" }, 429);
  }

  await c.env.KV.put(key, String(count + 1), { expirationTtl: 60 });
  return next();
});

// JWT protection for /api/*
app.use("/api/*", jwt({ secret: (c) => c.env.JWT_SECRET }));

app.get("/api/user/:id", async (c) => {
  const { id } = c.req.param();
  const user = await c.env.DB.prepare("SELECT * FROM users WHERE id = ?").bind(id).first();

  if (!user) return c.json({ error: "Not found" }, 404);
  return c.json(user);
});

export default app;

Hono is a lightweight router optimized for edge environments (Cloudflare Workers, Deno Deploy, Bun).

Response Transformation from Origin

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const response = await fetch(request);

    // Add security headers to all responses
    const newHeaders = new Headers(response.headers);
    newHeaders.set("X-Content-Type-Options", "nosniff");
    newHeaders.set("X-Frame-Options", "SAMEORIGIN");
    newHeaders.set("Referrer-Policy", "strict-origin-when-cross-origin");
    newHeaders.set(
      "Content-Security-Policy",
      "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'"
    );

    return new Response(response.body, {
      status: response.status,
      statusText: response.statusText,
      headers: newHeaders,
    });
  },
};

Geolocation and Content Personalization

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const cf = (request as any).cf as CfProperties;
    const url = new URL(request.url);

    // Redirect to localized site
    const countryLangMap: Record<string, string> = {
      RU: "ru", UA: "uk", DE: "de", FR: "fr",
    };

    const lang = countryLangMap[cf.country || ""] || "en";

    if (!url.pathname.match(/^\/(ru|uk|de|fr|en)\//)) {
      return Response.redirect(
        `${url.origin}/${lang}${url.pathname}${url.search}`,
        302
      );
    }

    // Pass geo data to origin via headers
    const modifiedRequest = new Request(request, {
      headers: {
        ...Object.fromEntries(request.headers),
        "X-Country": cf.country || "",
        "X-City": cf.city || "",
        "X-Timezone": cf.timezone || "",
      },
    });

    return fetch(modifiedRequest);
  },
};

R2: File Storage Without Egress Fee

Cloudflare R2 is S3-compatible storage without egress charges.

app.post("/upload", async (c) => {
  const formData = await c.req.formData();
  const file = formData.get("file") as File;

  const key = `uploads/${Date.now()}-${file.name}`;

  await c.env.R2.put(key, file.stream(), {
    httpMetadata: { contentType: file.type },
  });

  return c.json({ url: `https://cdn.yourdomain.com/${key}` });
});

app.get("/files/:key{.+}", async (c) => {
  const key = c.req.param("key");
  const object = await c.env.R2.get(key);

  if (!object) return c.json({ error: "Not found" }, 404);

  return new Response(object.body, {
    headers: {
      "Content-Type": object.httpMetadata?.contentType || "application/octet-stream",
      "Cache-Control": "public, max-age=31536000",
    },
  });
});

Durable Objects: State on Edge

For tasks requiring consistent state (counters, WebSocket rooms, distributed locks):

export class RateLimiter implements DurableObject {
  private requests = 0;

  async fetch(request: Request): Promise<Response> {
    this.requests++;

    if (this.requests > 1000) {
      return new Response("Rate limited", { status: 429 });
    }

    // Reset counter after 1 minute
    setTimeout(() => { this.requests = 0; }, 60000);

    return new Response("OK");
  }
}

Timeframe

Worker with routing and rate limiting — 2–3 days. Full API with D1, KV, R2, and CI/CD — 5–6 days.