Use absolute URLs for metadata (icon / social graph) (#30)

* Use absolute URLs for metadata (icon / social graph)

* Disable cache using "next" instead of "cache"

* Use cloudflare module from upstash
This commit is contained in:
Samy Pessé
2023-12-12 21:38:22 +01:00
committed by GitHub
parent f13e6cb55b
commit 2001e4dba5
4 changed files with 40 additions and 25 deletions
+13 -5
View File
@@ -3,7 +3,7 @@ import { notFound, redirect } from 'next/navigation';
import { SpaceContent } from '@/components/SpaceContent';
import { getDocument } from '@/lib/api';
import { PageHrefContext, baseUrl, pageHref } from '@/lib/links';
import { PageHrefContext, absoluteHref, baseUrl, pageHref } from '@/lib/links';
import { getPagePath } from '@/lib/pages';
import { PagePathParams, fetchPageData, getPathnameParam } from '../fetch';
@@ -53,25 +53,33 @@ export async function generateMetadata({ params }: { params: PagePathParams }):
return {
title: `${page.title} | ${space.title}`,
description: page.description,
description: page.description ?? '',
generator: 'GitBook',
// We pass `metadataBase` to avoid warnings from Next, but we still use absolute URLs
// as metadataBase doesn't seem to work well on next-on-cloudflare.
metadataBase: new URL(baseUrl()),
icons: {
icon: [
{
url: customIcon?.light ?? '.gitbook/icon?size=small&theme=light',
url:
customIcon?.light ??
absoluteHref('.gitbook/icon?size=small&theme=light', true),
type: 'image/png',
media: '(prefers-color-scheme: light)',
},
{
url: customIcon?.dark ?? '.gitbook/icon?size=small&theme=dark',
url:
customIcon?.dark ??
absoluteHref('.gitbook/icon?size=small&theme=dark', true),
type: 'image/png',
media: '(prefers-color-scheme: dark)',
},
],
},
openGraph: {
images: [customization.socialPreview.url ?? `.gitbook/ogimage/${page.id}`],
images: [
customization.socialPreview.url ?? absoluteHref(`.gitbook/ogimage/${page.id}`),
],
},
// TODO: remove once the development is finished
robots: space.visibility === 'public' && 0 ? 'index, follow' : 'noindex, nofollow',
+14 -17
View File
@@ -8,7 +8,7 @@ import {
} from '@gitbook/api';
import { headers } from 'next/headers';
import { cache, cacheResponse } from './cache';
import { cache, cacheResponse, noCacheFetchOptions } from './cache';
export interface ContentPointer {
spaceId: string;
@@ -72,10 +72,7 @@ export const getPublishedContentByUrl = cache(
secure: false,
format: 'json',
signal: signal,
// Cloudflare doesn't support the `cache` directive before next-on-pages patches the fetch function
// https://github.com/cloudflare/workerd/issues/698
// cache: 'no-store',
next: { revalidate: 0 },
...noCacheFetchOptions,
});
return cacheResponse(response);
@@ -91,7 +88,7 @@ export const getPublishedContentByUrl = cache(
*/
export const getSpace = cache('api.getSpace', async (spaceId: string) => {
const response = await api().spaces.getSpaceById(spaceId, {
cache: 'no-store',
...noCacheFetchOptions,
});
return cacheResponse(response);
});
@@ -103,18 +100,18 @@ export const getRevisionPages = cache('api.getRevisionPages', async (pointer: Co
const { data } = await (async () => {
if (pointer.revisionId) {
return api().spaces.listPagesInRevisionById(pointer.spaceId, pointer.revisionId, {
cache: 'no-store',
...noCacheFetchOptions,
});
}
if (pointer.changeRequestId) {
return api().spaces.listPagesInChangeRequest(spaceId, pointer.changeRequestId, {
cache: 'no-store',
...noCacheFetchOptions,
});
}
return api().spaces.listPages(pointer.spaceId, {
cache: 'no-store',
...noCacheFetchOptions,
});
})();
return { data: data.pages! };
@@ -134,7 +131,7 @@ export const getRevisionFile = cache(
pointer.revisionId,
fileId,
{
cache: 'no-store',
...noCacheFetchOptions,
},
);
}
@@ -145,13 +142,13 @@ export const getRevisionFile = cache(
pointer.changeRequestId,
fileId,
{
cache: 'no-store',
...noCacheFetchOptions,
},
);
}
return api().spaces.getFileById(pointer.spaceId, fileId, {
cache: 'no-store',
...noCacheFetchOptions,
});
})();
return cacheResponse(response);
@@ -170,7 +167,7 @@ export const getRevisionFile = cache(
*/
export const getCurrentRevision = cache('api.getCurrentRevision', async (spaceId: string) => {
const response = await api().spaces.getCurrentRevision(spaceId, {
cache: 'no-store',
...noCacheFetchOptions,
});
return cacheResponse(response);
});
@@ -180,7 +177,7 @@ export const getCurrentRevision = cache('api.getCurrentRevision', async (spaceId
*/
export const getDocument = cache('api.getDocument', async (spaceId: string, documentId: string) => {
const response = await api().spaces.getDocumentById(spaceId, documentId, {
cache: 'no-store',
...noCacheFetchOptions,
});
return cacheResponse(response);
});
@@ -190,7 +187,7 @@ export const getDocument = cache('api.getDocument', async (spaceId: string, docu
*/
export const getSpaceCustomization = cache('api.getSpaceCustomization', async (spaceId: string) => {
const response = await api().spaces.getSpacePublishingCustomizationById(spaceId, {
cache: 'no-store',
...noCacheFetchOptions,
});
return cacheResponse(response);
});
@@ -200,7 +197,7 @@ export const getSpaceCustomization = cache('api.getSpaceCustomization', async (s
*/
export const getCollection = cache('api.getCollection', async (collectionId: string) => {
const response = await api().collections.getCollectionById(collectionId, {
cache: 'no-store',
...noCacheFetchOptions,
});
return cacheResponse(response);
});
@@ -215,7 +212,7 @@ export const getCollectionSpaces = cache(
collectionId,
{},
{
cache: 'no-store',
...noCacheFetchOptions,
},
);
// TODO: do this filtering on the API side
+11 -1
View File
@@ -1,4 +1,4 @@
import { Redis } from '@upstash/redis';
import { Redis } from '@upstash/redis/cloudflare';
import parseCacheControl from 'parse-cache-control';
const cacheNamespace = process.env.UPSTASH_REDIS_NAMESPACE ?? 'gitbook';
@@ -23,6 +23,16 @@ export interface CacheResult<Result> {
ttl?: number;
}
/**
* Options to pass to the `fetch` call to disable the Next data-cache when wrapped in `cache()`.
*/
export const noCacheFetchOptions: Partial<RequestInit> = {
// Cloudflare doesn't support the `cache` directive before next-on-pages patches the fetch function
// https://github.com/cloudflare/workerd/issues/698
// cache: 'no-store',
next: { revalidate: 0 },
};
/**
* Cache data from an async function.
* We don't use the next.js cache because it has a 2MB limit.
+2 -2
View File
@@ -50,8 +50,8 @@ export function baseUrl(): string {
/**
* Create an absolute href in the current content.
*/
export function absoluteHref(href: string): string {
const base = basePath();
export function absoluteHref(href: string, withHost: boolean = false): string {
const base = withHost ? baseUrl() : basePath();
return `${base}${href.startsWith('/') ? href.slice(1) : href}`;
}