Реалізація White-Label версії веб-застосунку

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.
Розробка та обслуговування будь-яких видів сайтів:
Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Реалізація White-Label версії веб-застосунку
Складна
~2-4 тижні
Часті питання
Наші компетенції:
Етапи розробки
Останні роботи
  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

White-Label веб-приложение

White-label дозволяє клієнтам продавати ваш продукт під своїм брендом: власний домен, логотип, кольори, email-шаблони. Користувачі клієнта не знають про вашу платформу.

Архітектура White-Label

Два підходи до ізоляції:

По субдоменуacme.yourplatform.com або app.acmecorp.com (custom domain)

По записам DNS — клієнт додає CNAME: app.acmecorp.com → yourplatform.com

// middleware.ts: визначаємо тенанта по домену
export async function middleware(request: NextRequest) {
  const hostname = request.headers.get('host')!;
  const domain = hostname.replace(':3000', '');

  const tenant = await getTenantByDomain(domain);
  if (!tenant) {
    return NextResponse.rewrite(new URL('/404', request.url));
  }

  const response = NextResponse.next();
  response.headers.set('x-tenant-id', tenant.id);
  response.headers.set('x-tenant-slug', tenant.slug);
  return response;
}

Custom Domain: верифікація

export async function verifyCustomDomain(tenantId: string, domain: string) {
  const dns = await import('dns/promises');

  let cnameTarget: string;
  try {
    const records = await dns.resolveCname(domain);
    cnameTarget = records[0];
  } catch {
    return { verified: false, error: 'CNAME not found' };
  }

  const expectedCname = `${process.env.PLATFORM_DOMAIN}`;
  if (cnameTarget !== expectedCname) {
    return {
      verified: false,
      error: `CNAME must point to ${expectedCname}, found: ${cnameTarget}`
    };
  }

  await db.tenant.update({
    where: { id: tenantId },
    data: {
      customDomain: domain,
      customDomainVerifiedAt: new Date(),
    }
  });

  await addCloudflareCustomHostname(domain, tenantId);
  return { verified: true };
}

Брендинг: конфігурація тенанта

model TenantBranding {
  id              String  @id @default(cuid())
  tenantId        String  @unique
  logoUrl         String?
  faviconUrl      String?
  appName         String
  primaryColor    String  @default("#6366f1")
  secondaryColor  String  @default("#f1f5f9")
  fontFamily      String  @default("Inter")
  supportEmail    String?
  supportUrl      String?
  privacyUrl      String?
  termsUrl        String?
  footerText      String?
  hideWatermark   Boolean @default(false)
  customCss       String? @db.Text
  emailFromName   String?
  emailFromAddress String?
  emailLogoUrl    String?
}
export function TenantStylesheet({ branding }: { branding: TenantBranding }) {
  const css = `
    :root {
      --color-primary: ${branding.primaryColor};
      --color-secondary: ${branding.secondaryColor};
      --font-family: '${branding.fontFamily}', sans-serif;
    }
    ${branding.customCss ?? ''}
  `;

  return <style dangerouslySetInnerHTML={{ __html: css }} />;
}
// app/layout.tsx: динамічна метаінформація
export async function generateMetadata(): Promise<Metadata> {
  const tenantId = headers().get('x-tenant-id');
  const branding = await db.tenantBranding.findUnique({
    where: { tenantId: tenantId! }
  });

  return {
    title: branding?.appName ?? 'App',
    icons: { icon: branding?.faviconUrl ?? '/favicon.ico' },
  };
}

Email-шаблони з брендингом

export async function sendBrandedEmail(
  tenantId: string,
  to: string,
  template: string,
  variables: Record<string, string>
) {
  const branding = await db.tenantBranding.findUnique({
    where: { tenantId }
  });

  await resend.emails.send({
    from: branding?.emailFromAddress
      ? `${branding.emailFromName} <${branding.emailFromAddress}>`
      : `[email protected]`,
    to,
    subject: variables.subject,
    react: EmailTemplate({
      ...variables,
      logoUrl: branding?.emailLogoUrl,
      brandColor: branding?.primaryColor ?? '#6366f1',
      appName: branding?.appName ?? 'App',
      footerText: branding?.footerText,
    }),
  });
}

Розробка white-label системи з custom domains, брендингом та email-шаблонами — 5–10 робочих днів.