feat: build env options, formatting, selfhosting guide

This commit is contained in:
taskylizard 2025-03-13 13:57:06 +00:00
parent 88a1a989d9
commit 929bd44275
No known key found for this signature in database
GPG key ID: 1820131ED1A24120
39 changed files with 268 additions and 764 deletions

View file

@ -18,7 +18,7 @@ Please only use the store link if there's neither a site nor a Git repository av
3. Always check to see if the site you'd like to submit has a Discord / Telegram server you can link with it.
4. Find a suitable category for the link and then submit it by making a **[Pull Request](https://github.com/fmhy/edit/pulls)**.
4. Find a suitable category for the link and then submit it by making a **[Pull Request](https://github.com/fmhy/edit/pulls)**.
#### Don't Submit:
@ -102,7 +102,7 @@ Select edit button and make your changes.
### Manually setting up a development environment
#### Manually
#### Manual
1. Fork the repository by clicking the "Fork" button in the top right corner.
@ -126,10 +126,27 @@ You can use [nix](https://nixos.org/) to set up a development environment, we ha
3. Run `nix develop` to enter the development environment.
4. Make changes.
4. Make changes.
5. Exit the development environment by running `exit`.
6. Commit your changes and push them to your forked repository.
7. Create a pull request by clicking the "New Pull Request" button in your forked repository, and don't forget to explain why you think the site(s) in question should be removed, unstarred, and/or changed.
#### Keeping Your Fork Updated
To keep your fork up to date with the main repository:
```bash
# Add the upstream remote (only needed once)
git remote add upstream https://github.com/fmhy/edit.git
# Fetch upstream changes
git fetch upstream
# Merge upstream changes into your local main branch
git checkout main
git merge upstream/main
```

View file

@ -1,7 +1,7 @@
{
"**/*.ts": [
"/**",
"* Copyright (c) taskylizard. All rights reserved.",
"* Copyright (c) 2025 taskylizard. Apache License 2.0.",
"*",
"* Licensed under the Apache License, Version 2.0 (the \"License\");",
"* you may not use this file except in compliance with the License.",
@ -16,6 +16,15 @@
"* limitations under the License.",
"*/"
],
"**/*.css": [
"/**",
"* Copyright (c) 2025 taskylizard. Apache License 2.0.",
"* Licensed under the Apache License, Version 2.0 (the \"License\");",
"* you may not use this file except in compliance with the License.",
"* You may obtain a copy of the License at",
"* http://www.apache.org/licenses/LICENSE-2.0",
"*/"
],
"ignore": [
"node_modules",
"dist",

View file

@ -1,3 +0,0 @@
{
"extends": "stylelint-config-standard-scss"
}

View file

@ -1,6 +1,3 @@
> [!NOTE]
> The website is no longer receiving new features and is now in maintenance mode. Please refrain from opening issues or pull requests.
This is the API for the website and other related services.
Licensed under the Apache License v2.0, see [LICENSE](../docs/.vitepress/LICENSE) for more information.

View file

@ -1,5 +1,5 @@
/**
* Copyright (c) taskylizard. All rights reserved.
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View file

@ -1,3 +1,18 @@
/**
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export default defineEventHandler(async (event) => {
const { cloudflare } = event.context

View file

@ -1,5 +1,5 @@
/**
* Copyright (c) taskylizard. All rights reserved.
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View file

@ -1,5 +1,5 @@
/**
* Copyright (c) taskylizard. All rights reserved.
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View file

@ -1,5 +1,5 @@
/**
* Copyright (c) taskylizard. All rights reserved.
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View file

@ -1,8 +1,6 @@
{
"extends": "../.nitro/types/tsconfig.json",
"compilerOptions": {
"types": [
"@cloudflare/workers-types"
]
"types": ["@cloudflare/workers-types"]
}
}

View file

@ -1,6 +1,21 @@
/**
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Generated by Wrangler by running `wrangler types api/worker-configuration.d.ts`
interface Env {
STORAGE: KVNamespace;
RATE_LIMITER: RateLimit;
STORAGE: KVNamespace
RATE_LIMITER: RateLimit
}

View file

@ -1,57 +0,0 @@
{
"$schema": "https://biomejs.dev/schemas/1.8.3/schema.json",
"extends": [
"@taskylizard/biome-config",
"./.cache/imports.json"
],
"files": {
"ignore": [
"docs/.vitepress/**/*.vue",
"docs/.vitepress/vue-shim.d.ts",
".cache/imports.d.ts"
]
},
"formatter": {
"enabled": false
},
"css": {
"linter": {
"enabled": false
},
"formatter": {
"enabled": false
}
},
"json": {
"formatter": {
"enabled": false
},
"linter": {
"enabled": false
}
},
"vcs": {
"enabled": true,
"clientKind": "git"
},
"javascript": {
"globals": [
"defineNitroConfig",
"eventHandler",
"useRuntimeConfig",
"readValidatedBody",
"defineEventHandler"
]
},
"linter": {
"rules": {
"correctness": {
"noUndeclaredVariables": "off"
},
"style": {
"useFilenamingConvention": "off",
"noDefaultExport": "off"
}
}
}
}

View file

@ -1,6 +1,3 @@
> [!NOTE]
> The website is no longer receiving new features and is now in maintenance mode. Please refrain from opening issues or pull requests.
This is the website source code to be used with [VitePress](https://vitepress.dev/).
Licensed under the Apache License v2.0, see [LICENSE](./LICENSE) for more information.

View file

@ -18,7 +18,7 @@ import { generateFeed, generateImages, generateMeta } from './hooks'
import { defs, emojiRender, movePlugin } from './markdown/emoji'
import { headersPlugin } from './markdown/headers'
import { toggleStarredPlugin } from './markdown/toggleStarred'
import { transforms } from './transformer'
import { transformsPlugin } from './transformer'
// @unocss-include
@ -116,7 +116,7 @@ export default defineConfig({
filepath: './.cache/imports.json'
}
}),
transforms(),
transformsPlugin(),
{
name: 'custom:adjust-order',
configResolved(c) {
@ -145,7 +145,7 @@ export default defineConfig({
config(md) {
md.use(emojiRender)
md.use(toggleStarredPlugin)
md.use(headersPlugin)
meta.build.api && md.use(headersPlugin)
}
},
themeConfig: {

View file

@ -1,5 +1,5 @@
/**
* Copyright (c) taskylizard. All rights reserved.
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -15,6 +15,7 @@
*/
import type { DefaultTheme } from 'vitepress'
import consola from 'consola'
import { transform, transformGuide } from './transformer'
// @unocss-include
@ -23,14 +24,31 @@ export const meta = {
name: 'freemediaheckyeah',
description: 'The largest collection of free stuff on the internet!',
hostname: 'https://fmhy.net',
keywords: ['stream', 'movies', 'gaming', 'reading', 'anime']
keywords: ['stream', 'movies', 'gaming', 'reading', 'anime'],
build: {
api: true,
nsfw: true
}
}
if (process.env.FMHY_BUILD_NSFW === 'false') {
consola.info('FMHY_BUILD_NSFW is set to false, disabling NSFW content')
meta.build.nsfw = false
}
if (process.env.FMHY_BUILD_API === 'false') {
consola.info('FMHY_BUILD_API is set to false, disabling API component')
meta.build.api = false
}
const formatCommitRef = (commitRef: string) =>
`<a href="https://github.com/fmhy/edit/commit/${commitRef}">${commitRef.slice(0, 8)}</a>`
export const commitRef =
process.env.CF_PAGES && process.env.CF_PAGES_COMMIT_SHA
? `<a href="https://github.com/fmhy/edit/commit/${process.env.CF_PAGES_COMMIT_SHA
}">${process.env.CF_PAGES_COMMIT_SHA.slice(0, 8)}</a>`
: 'dev'
? formatCommitRef(process.env.CF_PAGES_COMMIT_SHA)
: process.env.COMMIT_REF
? formatCommitRef(process.env.COMMIT_REF)
: 'dev'
export const feedback = `<a href="/feedback" class="feedback-footer">Made with ❤</a>`
@ -113,17 +131,11 @@ export const socialLinks: DefaultTheme.SocialLink[] = [
{ icon: 'github', link: 'https://github.com/fmhy/edit' },
{ icon: 'discord', link: 'https://rentry.co/fmhy-invite' },
{
ariaLabel: 'Reddit',
icon: {
svg: '<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Reddit</title><path d="M12 0C5.373 0 0 5.373 0 12c0 3.314 1.343 6.314 3.515 8.485l-2.286 2.286C.775 23.225 1.097 24 1.738 24H12c6.627 0 12-5.373 12-12S18.627 0 12 0Zm4.388 3.199c1.104 0 1.999.895 1.999 1.999 0 1.105-.895 2-1.999 2-.946 0-1.739-.657-1.947-1.539v.002c-1.147.162-2.032 1.15-2.032 2.341v.007c1.776.067 3.4.567 4.686 1.363.473-.363 1.064-.58 1.707-.58 1.547 0 2.802 1.254 2.802 2.802 0 1.117-.655 2.081-1.601 2.531-.088 3.256-3.637 5.876-7.997 5.876-4.361 0-7.905-2.617-7.998-5.87-.954-.447-1.614-1.415-1.614-2.538 0-1.548 1.255-2.802 2.803-2.802.645 0 1.239.218 1.712.585 1.275-.79 2.881-1.291 4.64-1.365v-.01c0-1.663 1.263-3.034 2.88-3.207.188-.911.993-1.595 1.959-1.595Zm-8.085 8.376c-.784 0-1.459.78-1.506 1.797-.047 1.016.64 1.429 1.426 1.429.786 0 1.371-.369 1.418-1.385.047-1.017-.553-1.841-1.338-1.841Zm7.406 0c-.786 0-1.385.824-1.338 1.841.047 1.017.634 1.385 1.418 1.385.785 0 1.473-.413 1.426-1.429-.046-1.017-.721-1.797-1.506-1.797Zm-3.703 4.013c-.974 0-1.907.048-2.77.135-.147.015-.241.168-.183.305.483 1.154 1.622 1.964 2.953 1.964 1.33 0 2.47-.81 2.953-1.964.057-.137-.037-.29-.184-.305-.863-.087-1.795-.135-2.769-.135Z"/></svg>'
},
icon: 'reddit',
link: 'https://reddit.com/r/FREEMEDIAHECKYEAH'
},
{
ariaLabel: 'Bluesky',
icon: {
svg: '<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Bluesky</title><path d="M12 10.8c-1.087-2.114-4.046-6.053-6.798-7.995C2.566.944 1.561 1.266.902 1.565.139 1.908 0 3.08 0 3.768c0 .69.378 5.65.624 6.479.815 2.736 3.713 3.66 6.383 3.364.136-.02.275-.039.415-.056-.138.022-.276.04-.415.056-3.912.58-7.387 2.005-2.83 7.078 5.013 5.19 6.87-1.113 7.823-4.308.953 3.195 2.05 9.271 7.733 4.308 4.267-4.308 1.172-6.498-2.74-7.078a8.741 8.741 0 0 1-.415-.056c.14.017.279.036.415.056 2.67.297 5.568-.628 6.383-3.364.246-.828.624-5.79.624-6.478 0-.69-.139-1.861-.902-2.206-.659-.298-1.664-.62-4.3 1.24C16.046 4.748 13.087 8.687 12 10.8Z"/></svg>'
},
icon: 'bluesky',
link: 'https://bsky.app/profile/fmhy.net'
}
]
@ -141,14 +153,21 @@ export const nav: DefaultTheme.NavItem[] = [
{ text: '🔗 Bookmarks', link: 'https://github.com/fmhy/bookmarks' },
{ text: '✅ SafeGuard', link: 'https://github.com/fmhy/FMHY-SafeGuard' },
{ text: '📋 snowbin', link: 'https://pastes.fmhy.net' },
{ text: '💡 Site Hunting', link: 'https://www.reddit.com/r/FREEMEDIAHECKYEAH/wiki/find-new-sites/' },
{ text: '🏞 Wallpapers', link: '/other/wallpapers' },
{ text: '💙 Feedback', link: '/feedback' },
{
text: '💡 Site Hunting',
link: 'https://www.reddit.com/r/FREEMEDIAHECKYEAH/wiki/find-new-sites/'
},
{ text: '❓ FAQs', link: 'https://redd.it/xrxen7' },
{
text: '😇 SFW FMHY',
link: 'https://fmhy.xyz/'
}
},
{
text: '🏠 Selfhosting',
link: '/other/selfhosting'
},
{ text: '🏞 Wallpapers', link: '/other/wallpapers' },
{ text: '💙 Feedback', link: '/feedback' }
]
}
]
@ -166,8 +185,6 @@ export const sidebar: DefaultTheme.Sidebar | DefaultTheme.NavItemWithLink[] = [
text: '<span class="i-twemoji:light-bulb"></span> Contribute',
link: '/other/contributing'
},
// TODO: genetate sidebar from posts
{
text: 'Wiki',
collapsed: false,
@ -280,10 +297,12 @@ export const sidebar: DefaultTheme.Sidebar | DefaultTheme.NavItemWithLink[] = [
text: 'More',
collapsed: true,
items: [
{
text: '<span class="i-twemoji:no-one-under-eighteen"></span> NSFW',
link: 'https://rentry.co/NSFW-Checkpoint'
},
meta.build.nsfw
? {
text: '<span class="i-twemoji:no-one-under-eighteen"></span> NSFW',
link: 'https://rentry.co/NSFW-Checkpoint'
}
: {},
{
text: '<span class="i-twemoji:warning"></span> Unsafe Sites',
link: '/unsafesites'

View file

@ -1,5 +1,5 @@
/**
* Copyright (c) taskylizard. All rights reserved.
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View file

@ -1,5 +1,5 @@
/**
* Copyright (c) taskylizard. All rights reserved.
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,6 +21,7 @@ export function generateMeta(context: TransformContext, hostname: string) {
const { pageData } = context
if (pageData.isNotFound) return head
if (Object.keys(pageData.frontmatter).length === 0) return head
const url = `${hostname}/${pageData.relativePath.replace(/((^|\/)index)?\.md$/, '$2')}`

View file

@ -1,5 +1,5 @@
/**
* Copyright (c) taskylizard. All rights reserved.
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -88,14 +88,14 @@ async function generateImage({
const _page = getPage(url)
const title =
frontmatter.layout === 'home'
? frontmatter.hero.name ?? frontmatter.title
? (frontmatter.hero.name ?? frontmatter.title)
: frontmatter.title
? frontmatter.title
: _page?.title
const description =
frontmatter.layout === 'home'
? frontmatter.hero.tagline ?? frontmatter.description
? (frontmatter.hero.tagline ?? frontmatter.description)
: frontmatter.description
? frontmatter.description
: _page?.description

View file

@ -1,5 +1,5 @@
/**
* Copyright (c) taskylizard. All rights reserved.
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -22,7 +22,7 @@ import { Feed } from 'feed'
import { createContentLoader } from 'vitepress'
import { meta } from '../constants'
export async function generateFeed(config: SiteConfig): Promise {
export async function generateFeed(config: SiteConfig): Promise<void> {
const feed: Feed = new Feed({
id: meta.hostname,
link: meta.hostname,

View file

@ -1,5 +1,5 @@
/**
* Copyright (c) taskylizard. All rights reserved.
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View file

@ -1,5 +1,5 @@
/**
* Copyright (c) taskylizard. All rights reserved.
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View file

@ -1,5 +1,5 @@
/**
* Copyright (c) taskylizard. All rights reserved.
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View file

@ -1,3 +1,18 @@
/**
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Copyright (c) 2024 taskylizard
*
@ -53,10 +68,10 @@ export const headersPlugin = (md: MarkdownRenderer) => {
return result
}
let defaultRender = md.renderer.rules.link_open
const defaultRender = md.renderer.rules.link_open
md.renderer.rules.link_open = (tokens, idx, options, env, self) => {
const result = defaultRender!!!!!!!!!!!(tokens, idx, options, env, self)
const result = defaultRender!!!!!!!!!!(tokens, idx, options, env, self)
const meta = tokens[idx].meta
if (!meta || !meta.feedback) return result

View file

@ -1,5 +1,5 @@
/**
* Copyright (c) taskylizard. All rights reserved.
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View file

@ -1,7 +1,8 @@
<script setup lang="ts">
import type { FeedbackType } from '../../types/Feedback'
import { useRouter } from 'vitepress'
import { computed, reactive, ref } from 'vue'
import { feedbackOptions, getFeedbackOption, type FeedbackType } from '../../types/Feedback'
import { feedbackOptions, getFeedbackOption } from '../../types/Feedback'
const props = defineProps<{
heading?: string

View file

@ -3,7 +3,7 @@ import type { EnhanceAppContext } from 'vitepress'
import nprogress from 'nprogress'
/**
* Copyright (c) taskylizard. All rights reserved.
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View file

@ -1,5 +1,5 @@
/**
* Copyright (c) taskylizard. All rights reserved.
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View file

@ -1,5 +1,5 @@
/**
* Copyright (c) taskylizard. All rights reserved.
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View file

@ -1,5 +1,5 @@
/**
* Copyright (c) taskylizard. All rights reserved.
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,7 +19,7 @@ import { basename } from 'pathe'
import { excluded, getHeader } from './transformer/constants'
import { replaceUnderscore, transformer } from './transformer/core'
export function transforms(): Plugin {
export function transformsPlugin(): Plugin {
return {
name: 'custom:transform-content',
enforce: 'pre',

View file

@ -1,5 +1,7 @@
import { meta } from '../constants'
/**
* Copyright (c) taskylizard. All rights reserved.
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -146,7 +148,7 @@ export function getHeader(id: string) {
const description = '<p class="text-black dark:text-text-2">'
const feedback = '<Feedback />'
const feedback = meta.build.api ? '<Feedback />' : ''
const data = headers[id]
let header = '---\n'

View file

@ -1,5 +1,5 @@
/**
* Copyright (c) taskylizard. All rights reserved.
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -30,8 +30,8 @@ interface Replacer {
}
export const transformer = (text: string) => {
const handler: ProxyHandler = {
get(target, prop) {
const handler: ProxyHandler<{ text: string }> = {
get(target: { text: string }, prop: string | symbol) {
if (prop === 'transform') {
return (name: string, transforms: Transform[]): Replacer => {
consola.debug(`Starting transform ${name} with ${transforms}`)

View file

@ -1,5 +1,5 @@
/**
* Copyright (c) taskylizard. All rights reserved.
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View file

@ -1,5 +1,5 @@
/**
* Copyright (c) taskylizard. All rights reserved.
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View file

@ -1,5 +1,5 @@
/**
* Copyright (c) taskylizard. All rights reserved.
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

107
docs/other/selfhosting.md Normal file
View file

@ -0,0 +1,107 @@
---
title: Selfhosting FMHY
description: This guide will help you set up and run your own instance of FMHY locally.
---
# Selfhosting
This guide will help you set up and run your own instance of FMHY locally.
:::warning
Do note that you **must** differentiate your instance from the official site (fmhy.net) to avoid confusion. Steps to do so are given below.
:::
#### Prerequisites
- [Git](https://git-scm.com/downloads)
- [Node.js](https://nodejs.org/en/download/) - Use the latest available LTS, doesn't matter much
- [pnpm 9.12.2 or newer](https://pnpm.io/installation)
#### Step 1: Clone the Repository
```bash
git clone https://github.com/fmhy/edit.git
cd edit
```
#### Step 2: Install Dependencies
Install project dependencies using pnpm:
```bash
pnpm install
```
#### Step 3: Development Mode
To run the project in development mode:
```bash
# Start the documentation site in dev mode
pnpm docs:dev
# Start the API in dev mode (if needed)
pnpm api:dev
```
The development server will start at `http://localhost:5173` by default.
#### Step 4: Building for Production
You will need to update:
- the `meta` constant in `docs/.vitepress/constants.ts`
- `name`: Name of your instance
- `hostname`: Your domain
- `description`: Description of your instance
- `tags`: Opengraph tags
- `build`: Build options (can be configured with [Environment Variables](/other/selfhosting#environment-variables))
- `docs/index.md`
- `title`
- `description`
- `hero.name`
- `hero.tagline`
To build the project for production:
```bash
# Build the documentation site
pnpm docs:build
# Build the API (if needed) using the Node.js preset
NITRO_PRESET=node pnpm api:build
```
#### Step 5: Preview Production Build
To preview the production build locally:
```bash
# Preview the documentation site
pnpm docs:preview
# Preview the API (if needed)
pnpm api:preview
```
#### Step 6: Deploy
See the [VitePress deployment guide](https://vitepress.dev/guide/deploy) for more information.
#### Environment Variables
You may want to disable NSFW content (sidebar entry, page contents) and/or the API component for Feedback:
- `FMHY_BUILD_NSFW` - Disables NSFW content (experimental)
- `FMHY_BUILD_API` - Disables the API component
#### Troubleshooting
1. If you encounter Node.js version issues, ensure you're using Node.js 21+
2. For pnpm-related issues, make sure you're using pnpm 9+
3. Clear the cache if you encounter build issues:
```bash
rm -rf docs/.vitepress/cache
rm -rf docs/.vitepress/dist
pnpm install
```

View file

@ -1,5 +1,5 @@
/**
* Copyright (c) taskylizard. All rights reserved.
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View file

@ -1,5 +1,5 @@
{
"name": "fmhy",
"name": "@fmhy/website",
"packageManager": "pnpm@9.12.2",
"type": "module",
"engines": {
@ -16,9 +16,6 @@
"docs:dev": "vitepress dev docs/",
"docs:preview": "vitepress preview docs/",
"format": "prettier -w --cache --check .",
"lint": "biome lint .",
"lint:fix": "biome lint . --write",
"lint:fix:unsafe": "biome lint . --write --unsafe",
"og:dev": "x-satori -t ./docs/.vitepress/hooks/Template.vue -c ./.vitepress/hooks/satoriConfig.ts --dev"
},
"dependencies": {
@ -41,7 +38,6 @@
"zod": "^3.24.2"
},
"devDependencies": {
"@biomejs/biome": "^1.9.4",
"@cloudflare/workers-types": "^4.20241230.0",
"@ianvs/prettier-plugin-sort-imports": "^4.3.1",
"@iconify-json/carbon": "^1.2.5",
@ -51,7 +47,6 @@
"@iconify-json/simple-icons": "^1.2.12",
"@iconify-json/twemoji": "^1.2.1",
"@iconify/utils": "^2.3.0",
"@taskylizard/biome-config": "^1.0.5",
"@types/node": "^20.16.12",
"@types/nprogress": "^0.2.3",
"nitro-cloudflare-dev": "^0.2.2",
@ -59,8 +54,6 @@
"prettier-plugin-pkgsort": "^0.2.1",
"prettier-plugin-tailwindcss": "^0.6.11",
"sass": "^1.85.1",
"stylelint": "^16.15.0",
"stylelint-config-standard-scss": "^14.0.0",
"typescript": "^5.8.2",
"unplugin-auto-import": "^0.18.3",
"vite-plugin-optimize-exclude": "^0.0.1",

622
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/**
* Copyright (c) taskylizard. All rights reserved.
* Copyright (c) 2025 taskylizard. Apache License 2.0.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.