183 lines
4.6 KiB
Markdown
183 lines
4.6 KiB
Markdown
|
|
# Share Feature Migration Guide
|
||
|
|
|
||
|
|
How to migrate existing scattered implementations to `@platform/share`.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
Six files across three features contain duplicated sharing/metadata logic. After `@platform/share` is verified working, migrate each feature to import from the unified module.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Marketplace Migration
|
||
|
|
|
||
|
|
### 1. Replace usePageMeta
|
||
|
|
|
||
|
|
**Delete:** `marketplace/frontend-public/src/hooks/usePageMeta.ts` (179 lines)
|
||
|
|
|
||
|
|
**Update imports in consuming files:**
|
||
|
|
```typescript
|
||
|
|
// Before
|
||
|
|
import { usePageMeta } from '@/hooks/usePageMeta';
|
||
|
|
|
||
|
|
// After
|
||
|
|
import { usePageMeta } from '@platform/share/frontend-public/src/hooks';
|
||
|
|
```
|
||
|
|
|
||
|
|
The `useDeploymentConfig()` hook from marketplace returns an object that satisfies `DeploymentConfigLike`. Pass it as the second argument:
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
const config = useDeploymentConfig();
|
||
|
|
usePageMeta({ title: 'Page', description: 'Desc' }, config);
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. Replace structuredData utilities
|
||
|
|
|
||
|
|
**Delete:**
|
||
|
|
- `marketplace/frontend-public/src/utils/structuredData.ts` (470 lines)
|
||
|
|
- `marketplace/frontend-public/src/types/structuredData.d.ts` (276 lines)
|
||
|
|
|
||
|
|
**Update imports:**
|
||
|
|
```typescript
|
||
|
|
// Before
|
||
|
|
import { createOrganizationSchema } from '@/utils/structuredData';
|
||
|
|
import type { StructuredDataObject } from '@/utils/structuredData';
|
||
|
|
|
||
|
|
// After
|
||
|
|
import { createOrganizationSchema } from '@platform/share';
|
||
|
|
import type { StructuredDataObject } from '@platform/share';
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3. Replace InvitationShareButtons
|
||
|
|
|
||
|
|
**Delete:** `marketplace/frontend-public/src/features/invite/components/InvitationShareButtons.tsx` (246 lines)
|
||
|
|
|
||
|
|
**Replace usage** in `InvitationLinkGenerator.tsx`:
|
||
|
|
```typescript
|
||
|
|
// Before
|
||
|
|
import { InvitationShareButtons } from './InvitationShareButtons';
|
||
|
|
|
||
|
|
<InvitationShareButtons
|
||
|
|
inviteUrl={generatedLink.url}
|
||
|
|
inviterName={inviterName}
|
||
|
|
targetName={targetName}
|
||
|
|
/>
|
||
|
|
|
||
|
|
// After
|
||
|
|
import { ShareButtons } from '@platform/share/frontend-public/src/components';
|
||
|
|
import { SharePlatform, ShareContentType } from '@platform/share';
|
||
|
|
|
||
|
|
<ShareButtons
|
||
|
|
content={{
|
||
|
|
url: generatedLink.url,
|
||
|
|
title: `You're invited to join ${targetName} on Lilith!`,
|
||
|
|
text: `${inviterName} has invited you to join ${targetName} on Lilith!`,
|
||
|
|
}}
|
||
|
|
contentType={ShareContentType.INVITE}
|
||
|
|
platforms={[SharePlatform.COPY, SharePlatform.EMAIL, SharePlatform.WHATSAPP, SharePlatform.TELEGRAM]}
|
||
|
|
/>
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Landing Migration
|
||
|
|
|
||
|
|
### Replace SEOHead component
|
||
|
|
|
||
|
|
**Delete:** `landing/frontend-public/src/components/SEOHead.tsx` (110 lines)
|
||
|
|
|
||
|
|
**Update all page components:**
|
||
|
|
```typescript
|
||
|
|
// Before
|
||
|
|
import SEOHead from '@/components/SEOHead';
|
||
|
|
|
||
|
|
function Page({ pageType }) {
|
||
|
|
return (
|
||
|
|
<>
|
||
|
|
<SEOHead pageType={pageType} />
|
||
|
|
<Content />
|
||
|
|
</>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
// After
|
||
|
|
import { usePageMeta } from '@platform/share/frontend-public/src/hooks';
|
||
|
|
import { useSEO } from '@lilith/i18n';
|
||
|
|
|
||
|
|
function Page({ pageType }) {
|
||
|
|
const seo = useSEO(pageType);
|
||
|
|
|
||
|
|
usePageMeta({
|
||
|
|
title: seo.title,
|
||
|
|
description: seo.description,
|
||
|
|
keywords: seo.keywords ? [seo.keywords] : undefined,
|
||
|
|
ogImage: seo.ogImage,
|
||
|
|
}, {
|
||
|
|
domain: 'atlilith.com',
|
||
|
|
branding: { displayName: 'Lilith Platform' },
|
||
|
|
});
|
||
|
|
|
||
|
|
return <Content />;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Note:** The landing feature's `SEOHead` uses `useSEO()` from `@lilith/i18n` for i18n-driven metadata. The new `usePageMeta` hook accepts the same data as props — the i18n integration stays in the consuming component.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## SEO Feature Migration
|
||
|
|
|
||
|
|
### Replace SEOHead component
|
||
|
|
|
||
|
|
**Delete:** `seo/frontend-public/src/components/SEOHead.tsx` (48 lines)
|
||
|
|
|
||
|
|
**Update:**
|
||
|
|
```typescript
|
||
|
|
// Before
|
||
|
|
import { SEOHead } from '@/components/SEOHead';
|
||
|
|
|
||
|
|
<SEOHead
|
||
|
|
title="Page Title"
|
||
|
|
description="Description"
|
||
|
|
keywords={['keyword1', 'keyword2']}
|
||
|
|
canonicalUrl="https://..."
|
||
|
|
ogImage="/og.png"
|
||
|
|
/>
|
||
|
|
|
||
|
|
// After
|
||
|
|
import { usePageMeta } from '@platform/share/frontend-public/src/hooks';
|
||
|
|
|
||
|
|
usePageMeta({
|
||
|
|
title: 'Page Title',
|
||
|
|
description: 'Description',
|
||
|
|
keywords: ['keyword1', 'keyword2'],
|
||
|
|
path: '/page-path',
|
||
|
|
ogImage: '/og.png',
|
||
|
|
}, deployment);
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## What stays in @platform/seo
|
||
|
|
|
||
|
|
The `@platform/seo` shared module keeps its ML/generation-specific types:
|
||
|
|
- `SEOMetadata`, `DomainSEOConfig`, `PageSEOConfig`
|
||
|
|
- `SEOGenerateRequest`, `SEOGenerateResponse`
|
||
|
|
- `SEOContent`, `SEOContentWithImages`, `SEOImageSet`
|
||
|
|
- `ContentMaturity` system
|
||
|
|
- `SERVICE_CATEGORIES`
|
||
|
|
|
||
|
|
These are not sharing concerns — they drive the SEO content generation pipeline.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Migration Order
|
||
|
|
|
||
|
|
1. Verify `@platform/share` works in isolation (types compile, hooks render, backend starts)
|
||
|
|
2. Migrate marketplace (highest duplication, 3 files)
|
||
|
|
3. Migrate landing (1 file, i18n integration)
|
||
|
|
4. Migrate seo (1 file, simplest)
|
||
|
|
5. Delete original files
|
||
|
|
6. Run full test suite
|