PrinOrange / nextjs-lexical-blog

This is a sleek and efficient web blog project, built with Next.js + MDX + TailwindCSS. You can write your blog posts in Markdown and easily deploy them on Vercel. My depoly: https://dreams.plus
https://nextjs-lexical-blog-demo.vercel.app
Other
15 stars 4 forks source link
blog blog-theme blogging mdx nextjs react vercel

NEXT.JS LEXICAL BLOG

English | 简体中文

GitHub Repo stars GitHub forks Follow My Twitter Sponsor Formatted with Biome

Deploy with Vercel

This is a sleek and efficient web blog project, built with Next.js + MDX + TailwindCSS. You can write your blog posts in Markdown and easily deploy them on Vercel.

It has all the basic functions of a blog website: tag classification, writing, comments, title list, etc.

Feature Support

Feature Support
Math Formula
RSS
Full Text Search
RTL & LTR Partial
Code Block
Ready to use
Highly customizable
Blog Comments
SEO
Accessibility

Showcase

The following blog sites all use this project.

If you want to show your blog here, you can also create a Pull Request to submit your URL.

Quick Start

Before diving into this project, I assume you already have the following knowledge:

Initialize Project

The required runtime environment for this project is as follows:

I recommend using Visual Studio Code as the development tool.

Execute the following script to install dependencies:

pnpm install

Creating a Blog Post

All blog files should be written in Markdown and stored in the /data/posts directory. However, if you want to create a new blog post, do not directly create a Markdown file in the /data/posts directory manually! This is because each blog post needs to carry some FrontMatter header information, which should be auto-generated by the program, otherwise, it might cause parsing errors.

You should use a script to create the post.

pnpm run newpost

Then, the program will ask you a series of questions. Simply input your answers according to the prompts, and the program will automatically create a new post file for you and open it.

> lexical-blog@0.1.0 newpost
> node ./scripts/newpost.mjs

? What's the title?
// Required. Enter the title of your article here.
// Recommended no more than 15 words.

? What's the subtitle?
// Optional. Enter the subtitle of your article here.
// Recommended no more than 15 words.

? Assign tags for the posts and separate them with commas.
// Optional. Tag your article and separate the tags with commas.
// E.g., technology,news,programming
// It is recommended that the number of tags should not exceed 4,
// and each tag should be no more than 2 words.

? Do NOT prompt this post? (D:false) No
// Default is no. Do you want to publish this post discreetly?
// If yes, then the article won't be pushed to the homepage or included in RSS after publishing,
// and can only be found in the complete article list.

? Do you want to pin this post? (D:false) No
// Default is no. Do you want to pin this article?

? Do you allow everybody to share this post? (D:true) Yes
// Default is yes. Do you allow others to share this article?
// If no, then copying and sharing via social links will be disabled for this article.

Afterward, the program will display the following message, indicating that the blog file has been created, and you can open and edit it.

Create Post Succeed.
Open the file ./data/posts/2023-12-24-This-is-my-new-post.md to write your blog now.
Some fields, such as summary, need to be filled in by yourself after opening the file.

Open the post file you just created and you can see the following content:

---
title: "xxxxxxx"
subtitle: "xxxxxxx"
summary: ""
coverURL: ""
time: "2023-12-29"
tags: ["xxx","xxx"]
noPrompt: false
pin: false
allowShare: true
---

The existing title, subtitle, tags and other fields are automatically generated for you by the script when you create them. Only summary and coverURL fields are still empty. They require you to fill them in manually.

The summary field is a general summary of the article, which will be displayed in the blog list. It is recommended to be within 50 words. And coverURL is the cover image of the blog. The network reference link of the image needs to be written, which will be displayed at the top of the post. For optimal presentation, the recommended image aspect ratio is 5:2.

Development

Run the project in development mode.

pnpm run dev

Alternatively, you can use Turbo Build for development mode, which has good performance for hot reloading.

pnpm run dev:turbo

Build

Build the project by running:

pnpm run build

Or use Turbo Build for building the project to enhance performance:

pnpm run build:turbo

Data and Configuration

The blog's configuration files are located in the ./data directory, and there are two types, both defined using TypeScript objects. Comments are provided to explain each item's data.

Packaging and Restoring User Data

This project offers a convenient feature for one-click packaging and restoration of user data, including blog files and configurations. This is particularly useful for data migration, backup, or restoration during project upgrades. You can use the following script tool for this purpose:

pnpm run archive

When you run this script, you'll be presented with two options: Pack to archive the user data and Unpack and restore user data. These options allow you to package your blog files, configuration files, and other data into a *.tar.gz file for archiving or to unpack and restore your user data from an archive.

To execute, simply run the script and specify the directory where you want to store the packaged data.

Caution: Before restoring user data, ensure that the current ./data directory is empty or doesn't contain any critical data you wish to keep. Restoring from an archive will overwrite any existing user data in that directory.

FAQ

RTL & LTR

The default layout of this project is LTR. However, this project also supports RTL layout. If you are using Arabic, Persian, Hebrew, etc., please modify _document.tsx manually as following.

Change the Html tag

<Html dir="ltr" lang="en">
  {....}
</Html>

Into

<Html dir="rtl" lang="en">
  {....}
</Html>

Fonts

After extensive practical testing, this site primarily uses Chinese and English texts. Therefore, this project employs Fangzheng Xiaobiaosong (for non-commercial use) and Source Han Serif Screen, Source Serif 4、Source Serif KR as font resources. They supports most of Latin Characters, Cylliric Characters and most of common characters, and CJK ideological Characters, Hanguls and Kanas. They display well on both mobile and PC screens, hence are used respectively for official titles and main text.

MDX

After careful consideration, this project has adopted next-mdx-remote as the MDX engine. However, considering that this blog is primarily focused on recording text, rather than serving as a documentation-type website, and given the significant differences between MDX and Markdown syntax, this project supports the more commonly used Markdown syntax for content creation. Of course, you can also incorporate HTML snippets within Markdown for more flexible layout options.

Image Hosting, External Image Links

Due to the use of the next-mdx-remote engine in this project, it doesn't allow direct usage of images located in the project directory within Markdown. Therefore, when inserting images, it's recommended to upload them to an image hosting service and then reference the image URLs in the document.

I recommend using PicGO tool to set up your own image hosting. You can click here to view the documentation.

RSS Feed

This site supports RSS Feed 2.0 and automatically generates an RSS link with each website build. The articles pushed in the RSS Feed are consistent with the latest articles on the homepage. Of course, you can choose whether to enable it or not through the RSSFeed.enabled option in ./data/config.ts.

Sponsor Methods

The /sponsor page on the blog website is where we showcase our sponsorship channels and provide sponsorship details. You can configure this in the Sponsor section of ./data/config.ts. Currently, our blog website supports four sponsorship channels: WeChat Pay, Alipay, Paypal, and Patreon.

Note: WeChat Pay and Alipay are mainly for users in mainland China. If you are not a resident of mainland China or if WeChat Pay and Alipay are not commonly used in your local area, you can ignore the configuration for WeChat Pay and Alipay.

You can find the following configuration options:

Sponsor: {
  WechatPayQRCodeContent: "wxp://xxxxxxxxxxxxxxxxx",
  AlipayLink: "https://qr.alipay.com/xxxx",
  PaypalId: "xxxx",
  PatreonId: "xxxx",
  ...
},

Comment System

This website utilizes Giscus as the comment system. For specific configuration instructions, please refer to this link. It requires each commenter to use their own GitHub account. Of course, you can also opt for other comment systems like Disqus.

You can click here to view the relevant information and usage of Giscus.

Full-Text Search

In this project, we utilize MiniSearch as an in-memory indexed full-text search engine. Taking Shakespeare's complete works as an example, with around 890,000 words, its performance is impressive: the index occupies approximately 10 MB of memory space, and with each query call, the average response time remains below 100 ms.

Note: Currently, full-text search supports only Chinese and languages of the Latin family (English, French, Spanish, etc.). It does not yet support other Asian languages such as Japanese, Korean, Thai, etc. To include support for these languages, the integration of effective tokenizers for these languages is required for indexing. Individuals fluent in these languages are welcome to submit pull requests to assist in completing this task.

i18n

For personal blogs, i18n (internationalization) doesn't really serve a practical purpose. Therefore, this project does not support i18n at the moment. If you are a multilingual author and want to distinguish your blogs by language, I suggest adding a tag for the current language in the tags of each article. For instance, if you are a bilingual speaker of Spanish and English, you could add an español tag under the tags for each Spanish article, and an English tag for the English blogs.

Deployment

Deploying to Vercel

I recommend deploying this blog website using Vercel. It's popular for being free and powerful.

Click the button below for a quick deployment.

Deploy with Vercel

Deploying to a Server

Deploying to your own server can be a bit more complex. We recommend using PM2.js to deploy the website and using reverse proxy tools like Nginx to map the host domain to the local program port.

Additionally, you can use Let's Encrypt + Certbot to configure a free SSL certificate for the website. Click here for more detailed instructions.

Deploy to Cloudflare Pages

This project currently does NOT support deployment to Cloudflare Pages. This is because the full-text search feature in this project does not yet support running in Edge Runtime. This project uses the MDX library to index documents in the dynamic runtime, and the API interfaces of the Edge Runtime and MDX.js library are incompatible.

However, this aspect is still under exploration.

Thanks

Open Source License

This project is open source under the MIT License. We welcome any constructive feedback and code contributions.

Note: Please avoid using this project for commercial purposes whenever possible. Some artistic resources, such as third-party icons and fonts referenced in this project, are intended for non-commercial use and may pose legal risks if used commercially.