From 35a8ea4af5de40b1fb174870f511b942da907a27 Mon Sep 17 00:00:00 2001 From: ahaapple Date: Sun, 3 Nov 2024 22:45:44 +0800 Subject: [PATCH] Update doc and blog footer --- README.md | 7 +++- .../[locale]/(docs)/docs/[[...slug]]/page.tsx | 12 ++----- .../(marketing)/blog/[...slug]/page.tsx | 11 ++---- frontend/components/layout/product-footer.tsx | 34 +++++++++++++++++++ frontend/config.ts | 2 ++ .../blog/en/couldflare-next-on-page-edge.mdx | 18 ++++++++-- .../blog/zh/couldflare-next-on-page-edge.mdx | 20 +++++++++-- 7 files changed, 80 insertions(+), 24 deletions(-) create mode 100644 frontend/components/layout/product-footer.tsx diff --git a/README.md b/README.md index 36b58785..4e3c40f6 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,10 @@ MemFree is equipped with powerful features that cater to various search and prod - [One Command Deploy MemFree Vector on Fly.io](https://www.memfree.me/docs/deploy-memfree-fly-io) +### 6 Deploy MemFree on Cloudflare Pages + +- [How to migrate MemFree from Vercel to Cloudflare next-on-pages](https://www.memfree.me/blog/couldflare-next-on-page-edge) + ## Self-Hosted Installations ### Prerequisites @@ -210,8 +214,9 @@ MemFree is backed by [MemFree](https://www.memfree.me/) and licensed under [MIT] ## Powered By MemFree +- [PageGen AI Page Generator](https://pagegen.ai/) +- [MemFree Hybrid AI Search](https://www.memfree.me) - [React + Shadcn UI Preview](https://reactshadcn.com) -- [PageGen - AI Page Generator](https://pagegen.ai/) ## Star History diff --git a/frontend/app/[locale]/(docs)/docs/[[...slug]]/page.tsx b/frontend/app/[locale]/(docs)/docs/[[...slug]]/page.tsx index 811683a2..66f36843 100644 --- a/frontend/app/[locale]/(docs)/docs/[[...slug]]/page.tsx +++ b/frontend/app/[locale]/(docs)/docs/[[...slug]]/page.tsx @@ -17,6 +17,7 @@ import { type Locale, routing } from '@/i18n/routing'; import { unstable_setRequestLocale } from 'next-intl/server'; import Link from 'next/link'; import { buttonVariants } from '@/components/ui/button'; +import { ProductFooter } from '@/components/layout/product-footer'; interface DocPageProps { params: { @@ -94,7 +95,7 @@ export default async function DocPage({ params }: DocPageProps) { const toc = await getTableOfContents(doc.body.raw); return ( -
+
@@ -108,14 +109,7 @@ export default async function DocPage({ params }: DocPageProps) {
-
- - Hybrid AI Search Now - - - AI Page Generator Now - -
+
); } diff --git a/frontend/app/[locale]/(marketing)/blog/[...slug]/page.tsx b/frontend/app/[locale]/(marketing)/blog/[...slug]/page.tsx index 9b1bcb9d..1a282b30 100644 --- a/frontend/app/[locale]/(marketing)/blog/[...slug]/page.tsx +++ b/frontend/app/[locale]/(marketing)/blog/[...slug]/page.tsx @@ -13,6 +13,7 @@ import { buttonVariants } from '@/components/ui/button'; import { PageGenUrl, siteConfig } from '@/config'; import { unstable_setRequestLocale } from 'next-intl/server'; import { type Locale, routing } from '@/i18n/routing'; +import { ProductFooter } from '@/components/layout/product-footer'; interface PostPageProps { params: { @@ -106,15 +107,7 @@ export default async function PostPage({ params }: PostPageProps) { )} -
- - Hybrid AI Search Now - - - AI Page Generator Now - -
- +
See all posts diff --git a/frontend/components/layout/product-footer.tsx b/frontend/components/layout/product-footer.tsx new file mode 100644 index 00000000..415307f7 --- /dev/null +++ b/frontend/components/layout/product-footer.tsx @@ -0,0 +1,34 @@ +import { PageGenUrl, ReactShadcnUrl, SearchUrl } from '@/config'; +import Link from 'next/link'; + +export function ProductFooter() { + return ( +
+
+ + Hybrid AI Search + + | + + AI Page Generator + + | + + React Shadcn UI Preview + +
+
+ ); +} diff --git a/frontend/config.ts b/frontend/config.ts index a225b337..b56e8306 100644 --- a/frontend/config.ts +++ b/frontend/config.ts @@ -15,6 +15,8 @@ import { const site_url = 'https://www.memfree.me'; export const PageGenUrl = 'https://pagegen.ai'; +export const SearchUrl = 'https://www.memfree.me'; +export const ReactShadcnUrl = 'https://reactshadcn.com'; export const siteConfig: SiteConfig = { name: 'MemFree', diff --git a/frontend/content/blog/en/couldflare-next-on-page-edge.mdx b/frontend/content/blog/en/couldflare-next-on-page-edge.mdx index 45056281..a9c452c5 100644 --- a/frontend/content/blog/en/couldflare-next-on-page-edge.mdx +++ b/frontend/content/blog/en/couldflare-next-on-page-edge.mdx @@ -1,5 +1,5 @@ --- -title: How to migrate MemFree from vercel to cloudflare next-on-pages +title: How to migrate MemFree from Vercel to Cloudflare next-on-pages description: Issues and solutions for migrating MemFree from vercel to cloudflare next-on-pages image: /images/blog/blog-post-3.jpg date: '2024-11-03' @@ -97,7 +97,21 @@ The documentation and blog sections of MemFree were generated using `contentlaye EvalError: Code generation from strings disallowed for this context ``` -This limitation is unreasonable, as static pages can be fully generated during the build process without needing runtime generation. Ultimately, I replaced `contentlayer2` with `next/mdx`, allowing for complete static page generation during compilation. +The reason for the error with contentlayer2 is that it uses the Function constructor, which is not allowed in edge environments. + +```ts +export const getMDXComponent = (code: string, globals: Record = {}): React.FC => { + const scope = { React, ReactDOM, _jsx_runtime, ...globals }; + const fn = new Function(...Object.keys(scope), code); + return fn(...Object.values(scope)).default; +}; + +export const useMDXComponent = (code: string, globals: Record = {}) => { + return React.useMemo(() => getMDXComponent(code, globals), [code, globals]); +}; +``` + +However, this is actually unnecessary because static pages can be fully generated during the build process without the need for runtime dynamic rendering. In the end, I replaced contentlayer2 with `next/mdx`, which completely replaces mdx with static pages during the compilation phase. For more details, refer to [Markdown and MDX](https://nextjs.org/docs/pages/building-your-application/configuring/mdx). diff --git a/frontend/content/blog/zh/couldflare-next-on-page-edge.mdx b/frontend/content/blog/zh/couldflare-next-on-page-edge.mdx index fa879c30..355bef64 100644 --- a/frontend/content/blog/zh/couldflare-next-on-page-edge.mdx +++ b/frontend/content/blog/zh/couldflare-next-on-page-edge.mdx @@ -1,5 +1,5 @@ --- -title: How to migrate MemFree from vercel to cloudflare next-on-pages +title: How to migrate MemFree from Vercel to Cloudflare next-on-pages description: Issues and solutions for migrating MemFree from vercel to cloudflare next-on-pages image: /images/blog/blog-post-3.jpg date: '2024-11-03' @@ -88,13 +88,27 @@ NEXT_PUBLIC 的 env 变量在 cloudflare next-on-pages 中无法直接访问, ### 6 用 next/mdx 替换 contentlayer2 -memfree的doc和blog 都是利用contentlayer2 基于mdx文件生成的静态页面, 使用 contentlayer2,在 cloudflare next-on-pages 中会得到下面的报错: +MemFree 的 doc和blog 都是利用 contentlayer2 基于mdx文件生成的静态页面, 使用 contentlayer2,在 cloudflare next-on-pages 中会得到下面的报错: ```ts EvalError: Code generation from strings disallowed for this context ``` -但是这一点其实是不合理的,因为是静态页面完全可以在build期间全部生成,不需要运行时动态生成。 最后我使用 next/mdx 替换了 contentlayer2,在编译期间将 mdx 完全替换成静态页面。 +contentlayer2 会报错的原因是contentlayer2 用到了 Function 构造函数,这个在 edge 环境中是不允许的。 + +```ts +export const getMDXComponent = (code: string, globals: Record = {}): React.FC => { + const scope = { React, ReactDOM, _jsx_runtime, ...globals }; + const fn = new Function(...Object.keys(scope), code); + return fn(...Object.values(scope)).default; +}; + +export const useMDXComponent = (code: string, globals: Record = {}) => { + return React.useMemo(() => getMDXComponent(code, globals), [code, globals]); +}; +``` + +但这是其实是没有必要的,因为是静态页面完全可以在build期间全部生成,不需要运行时动态渲染。 最后我使用 next/mdx 替换了 contentlayer2,在编译期间将 mdx 完全替换成静态页面。 大家可以参考 [Markdown and MDX](https://nextjs.org/docs/pages/building-your-application/configuring/mdx)