Skip to content

Commit

Permalink
feat: seo handling
Browse files Browse the repository at this point in the history
  • Loading branch information
nicholasio committed Jul 19, 2024
1 parent ca94535 commit c6f1016
Show file tree
Hide file tree
Showing 25 changed files with 422 additions and 67 deletions.
116 changes: 115 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@
"react-inspector": "^6.0.1",
"swr": "^2.2.5",
"xss": "^1.0.15",
"deepmerge": "^4.3.1"
"deepmerge": "^4.3.1",
"schema-dts": "^1.1.2"
},
"peerDependencies": {
"react": ">= 17.0.2"
Expand Down
11 changes: 6 additions & 5 deletions packages/core/src/data/strategies/SearchFetchStrategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { PostsArchiveFetchStrategy, PostsArchiveParams } from './PostsArchiveFet
import { endpoints } from '../utils';
import { apiGet } from '../api';
import { addQueryArgs, getWPUrl } from '../../utils';
import { PostEntity, QueriedObject } from '../types';
import { PostEntity, QueriedObject, YoastJSON } from '../types';
import { FetchOptions } from './AbstractFetchStrategy';

/**
Expand Down Expand Up @@ -45,7 +45,7 @@ export class SearchFetchStrategy<
*/
async fetcher(url: string, params: Partial<P>, options: Partial<FetchOptions> = {}) {
const { burstCache = false } = options;
let seo_json: Record<string, any> = {};
let seo_json: YoastJSON | null = null;
let seo: string = '';

// Request SEO data.
Expand All @@ -70,12 +70,13 @@ export class SearchFetchStrategy<
type: 'post',
subtype: params.postType ?? 'post',
yoast_head: seo,
yoast_head_json: {
...seo_json,
},
},
};

if (seo_json && queriedObject.search) {
queriedObject.search.yoast_head_json = seo_json;
}

const response = await super.fetcher(url, params, { ...options, throwIfNotFound: false });

return {
Expand Down
13 changes: 7 additions & 6 deletions packages/core/src/data/strategies/SearchNativeFetchStrategy.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getSiteBySourceUrl, addQueryArgs, getWPUrl } from '../../utils';
import { endpoints } from '../utils';
import { apiGet } from '../api';
import { PostSearchEntity, TermSearchEntity, QueriedObject } from '../types';
import { PostSearchEntity, TermSearchEntity, QueriedObject, YoastJSON } from '../types';
import { searchMatchers } from '../utils/matchers';
import { parsePath } from '../utils/parsePath';
import { FetchOptions, AbstractFetchStrategy, EndpointParams } from './AbstractFetchStrategy';
Expand Down Expand Up @@ -124,7 +124,7 @@ export class SearchNativeFetchStrategy<
*/
async fetcher(url: string, params: Partial<P>, options: Partial<FetchOptions> = {}) {
const { burstCache = false } = options;
let seo_json: Record<string, any> = {};
let seo_json: YoastJSON | null = null;
let seo: string = '';

// Request SEO data.
Expand All @@ -142,7 +142,7 @@ export class SearchNativeFetchStrategy<
);

seo = result.json.html ?? null;
seo_json = { ...result.json.json };
seo_json = { ...(result.json.json as YoastJSON) };
} catch (e) {
// do nothing
}
Expand All @@ -153,12 +153,13 @@ export class SearchNativeFetchStrategy<
type: params.type ?? 'post',
subtype: params.subtype ?? 'post',
yoast_head: seo,
yoast_head_json: {
...seo_json,
},
},
};

if (seo_json && queriedObject.search) {
queriedObject.search.yoast_head_json = seo_json;
}

const response = await super.fetcher(url, params, {
...options,
throwIfNotFound: false,
Expand Down
13 changes: 3 additions & 10 deletions packages/core/src/data/types/entities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
* Those schemas are accessible making an OPTIONS call to each endpoint.
*/

import { YoastJSON } from './yoast';

/**
* Empty interface from which all entities inherit.
*/
export interface Entity {
yoast_head_json?: Record<string, any> | null;
yoast_head_json?: YoastJSON | null;
yoast_head?: string | null;
[k: string]: unknown;
}
Expand Down Expand Up @@ -109,9 +111,6 @@ export interface PostTypeEntity extends Entity {
* Whether or not the object can be pinged.
*/
ping_status: 'open' | 'closed';

yoast_head_json?: Record<string, any> | null;
yoast_head?: string | null;
}

/**
Expand Down Expand Up @@ -474,9 +473,6 @@ export interface TermEntity extends Entity {
* Meta fields.
*/
meta: Record<string, unknown>;

yoast_head_json?: Record<string, any> | null;
yoast_head?: string | null;
}

/**
Expand Down Expand Up @@ -543,9 +539,6 @@ export interface AuthorEntity extends Entity {
* Meta fields.
*/
meta: Record<string, unknown>;

yoast_head_json?: Record<string, any> | null;
yoast_head?: string | null;
}

/**
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/data/types/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './entities';
export * from './yoast';
53 changes: 53 additions & 0 deletions packages/core/src/data/types/yoast.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import type { Graph } from 'schema-dts';

export type YoastJSON = {
title: string;
description: string;
robots: {
index: 'index' | 'noindex';
follow: 'follow' | 'nofollow';
'max-snippet'?: number;
'max-image-preview'?: 'none' | 'standard' | 'large';
'max-video-preview'?: string | number;
};
canonical: string;
og_locale?: string;
og_type?:
| 'article'
| 'book'
| 'music.song'
| 'music.album'
| 'music.playlist'
| 'music.radio_station'
| 'profile'
| 'website'
| 'video.tv_show'
| 'video.other'
| 'video.movie'
| 'video.episode';
og_title?: string;
og_description?: string;
og_image?: {
width?: number;
height?: number;
size?: string;
path?: string;
alt?: string;
pixels?: number;
id?: string;
url: string;
};
og_url?: string;
og_site_name?: string;
article_publisher?: string;
article_author?: string;
article_published_time?: string;
article_modified_time?: string;
author?: string;
twitter_card?: string;
twitter_creator?: string;
twitter_site?: string;
twitter_misc?: Record<string, string>;
schema?: Graph;
status?: number;
};
15 changes: 1 addition & 14 deletions packages/next/src/components/Yoast.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { createElement, Fragment } from 'react';
import {
HTMLReactParser as parse,
removeSourceUrl,
attributesToProps,
DOMNode,
domToReact,
Expand All @@ -11,19 +10,7 @@ import {
} from '@headstartwp/core';
import { useSettings } from '@headstartwp/core/react';
import Head from 'next/head.js';

export function convertUrl(url: string, hostUrl: string, sourceUrl: string) {
if (!url.startsWith(sourceUrl)) {
return url;
}

return `${hostUrl}${removeSourceUrl({
link: url,
publicUrl: hostUrl,
backendUrl: sourceUrl,
nonEmptyLink: false,
})}`;
}
import { convertUrl } from '../utils/convertUrl';

type Props = {
seo: {
Expand Down
1 change: 1 addition & 0 deletions packages/next/src/rsc/data/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from '../../data/convertToPath';
export * from './queries';
export * from './seo';
Loading

0 comments on commit c6f1016

Please sign in to comment.