diff --git a/AGENTS.md b/AGENTS.md index 31e2149f3..59f6a8dbe 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,13 +1 @@ See [CLAUDE.md](./CLAUDE.md) for all project instructions and guidelines. - -## Skills - -Project-specific skills (patterns, conventions, and implementation guides) are located in [`.claude/skills/`](./.claude/skills/). Each skill has a `SKILL.md` describing the pattern: - -- **[Dependency Injection](./.claude/skills/dependency-injection/SKILL.md)** — Vue provide/inject DI layer using `createContext` -- **[Cross-Platform Pages](./.claude/skills/cross-platform-pages/SKILL.md)** — Shared component architecture across Nuxt and Tauri frontends -- **[Multistage Modals](./.claude/skills/multistage-modals/SKILL.md)** — Wizard-like modal flows with `MultiStageModal` -- **[Figma MCP](./.claude/skills/figma-mcp/SKILL.md)** — Translating Figma designs to Modrinth Vue components -- **[i18n Convert](./.claude/skills/i18n-convert/SKILL.md)** — Converting hard-coded strings to vue-i18n localization -- **[API Module](./.claude/skills/api-module/SKILL.md)** — Adding new endpoint modules to `@modrinth/api-client` -- **[TanStack Query](./.claude/skills/tanstack-query/SKILL.md)** — Server state management with `@tanstack/vue-query` v5 diff --git a/CLAUDE.md b/CLAUDE.md index 6161ef281..7cb1dad1b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -84,3 +84,15 @@ Each project may have its own `CLAUDE.md` with detailed instructions: ### General - Do not create new non-source code files (e.g. Bash scripts, SQL scripts) unless explicitly prompted to + +## Skills + +Project-specific skills (patterns, conventions, and implementation guides) are located in [`.claude/skills/`](./.claude/skills/). Each skill has a `SKILL.md` describing the pattern: + +- **[Dependency Injection](./.claude/skills/dependency-injection/SKILL.md)** — Vue provide/inject DI layer using `createContext` +- **[Cross-Platform Pages](./.claude/skills/cross-platform-pages/SKILL.md)** — Shared component architecture across Nuxt and Tauri frontends +- **[Multistage Modals](./.claude/skills/multistage-modals/SKILL.md)** — Wizard-like modal flows with `MultiStageModal` +- **[Figma MCP](./.claude/skills/figma-mcp/SKILL.md)** — Translating Figma designs to Modrinth Vue components +- **[i18n Convert](./.claude/skills/i18n-convert/SKILL.md)** — Converting hard-coded strings to vue-i18n localization +- **[API Module](./.claude/skills/api-module/SKILL.md)** — Adding new endpoint modules to `@modrinth/api-client` +- **[TanStack Query](./.claude/skills/tanstack-query/SKILL.md)** — Server state management with `@tanstack/vue-query` v5 diff --git a/apps/frontend/nuxt.config.ts b/apps/frontend/nuxt.config.ts index f308b1a5a..36d1ea5f3 100644 --- a/apps/frontend/nuxt.config.ts +++ b/apps/frontend/nuxt.config.ts @@ -111,6 +111,8 @@ export default defineNuxtConfig({ const docTemplates = Object.keys( await import('./src/templates/docs/index.ts').then((m) => m.default), ) + const blogArticles = await import('@modrinth/blog').then((m) => m.articles) + const { getChangelog } = await import('@modrinth/utils') nitroConfig.prerender = nitroConfig.prerender || {} nitroConfig.prerender.routes = nitroConfig.prerender.routes || [] @@ -120,6 +122,15 @@ export default defineNuxtConfig({ for (const template of docTemplates) { nitroConfig.prerender.routes.push(`/_internal/templates/doc/${template}`) } + nitroConfig.prerender.routes.push('/news') + for (const article of blogArticles) { + nitroConfig.prerender.routes.push(`/news/article/${article.slug}`) + } + nitroConfig.prerender.routes.push('/news/changelog') + for (const entry of getChangelog()) { + const id = entry.version ?? entry.date.unix() + nitroConfig.prerender.routes.push(`/news/changelog/${entry.product}/${id}`) + } }, async 'build:before'() { // 30 minutes diff --git a/apps/frontend/src/pages/news/changelog/[product]/[date].vue b/apps/frontend/src/pages/news/changelog/[product]/[date].vue index d481f0415..1ad2bca81 100644 --- a/apps/frontend/src/pages/news/changelog/[product]/[date].vue +++ b/apps/frontend/src/pages/news/changelog/[product]/[date].vue @@ -9,13 +9,9 @@ const changelogEntry = computed(() => route.params.date ? getChangelog().find((x) => { if (x.product === route.params.product) { - console.log('Found matching product!') - if (x.version && x.version === route.params.date) { - console.log('Found matching version!') return x } else if (x.date.unix() === Number(route.params.date as string)) { - console.log('Found matching date!') return x } } diff --git a/apps/frontend/src/public/news/article/introducing-server-projects/compatability-type-config.mp4 b/apps/frontend/src/public/news/article/introducing-server-projects/compatability-type-config.mp4 new file mode 100644 index 000000000..7ddd50f61 Binary files /dev/null and b/apps/frontend/src/public/news/article/introducing-server-projects/compatability-type-config.mp4 differ diff --git a/apps/frontend/src/public/news/article/introducing-server-projects/joining-a-server.webp b/apps/frontend/src/public/news/article/introducing-server-projects/joining-a-server.webp new file mode 100644 index 000000000..d4f7061b2 Binary files /dev/null and b/apps/frontend/src/public/news/article/introducing-server-projects/joining-a-server.webp differ diff --git a/apps/frontend/src/public/news/article/introducing-server-projects/project-discovery.webp b/apps/frontend/src/public/news/article/introducing-server-projects/project-discovery.webp new file mode 100644 index 000000000..384168261 Binary files /dev/null and b/apps/frontend/src/public/news/article/introducing-server-projects/project-discovery.webp differ diff --git a/apps/frontend/src/public/news/article/introducing-server-projects/server-discovery-in-app.mp4 b/apps/frontend/src/public/news/article/introducing-server-projects/server-discovery-in-app.mp4 new file mode 100644 index 000000000..6e476ab1b Binary files /dev/null and b/apps/frontend/src/public/news/article/introducing-server-projects/server-discovery-in-app.mp4 differ diff --git a/apps/frontend/src/public/news/article/introducing-server-projects/server-project-updates.webp b/apps/frontend/src/public/news/article/introducing-server-projects/server-project-updates.webp new file mode 100644 index 000000000..e17f79486 Binary files /dev/null and b/apps/frontend/src/public/news/article/introducing-server-projects/server-project-updates.webp differ diff --git a/apps/frontend/src/public/news/article/introducing-server-projects/thumbnail.webp b/apps/frontend/src/public/news/article/introducing-server-projects/thumbnail.webp new file mode 100644 index 000000000..d6e7aff66 Binary files /dev/null and b/apps/frontend/src/public/news/article/introducing-server-projects/thumbnail.webp differ diff --git a/apps/frontend/src/public/news/feed/articles.json b/apps/frontend/src/public/news/feed/articles.json index 3e37fa820..21ed8591b 100644 --- a/apps/frontend/src/public/news/feed/articles.json +++ b/apps/frontend/src/public/news/feed/articles.json @@ -1,5 +1,12 @@ { "articles": [ + { + "title": "Introducing Server Projects", + "summary": "A new project type made for seamless modded multiplayer on Modrinth.", + "thumbnail": "https://modrinth.com/news/article/introducing-server-projects/thumbnail.webp", + "date": "2026-03-02T15:00:00.000Z", + "link": "https://modrinth.com/news/article/introducing-server-projects" + }, { "title": "Streamlined Version Creation", "summary": "Version creation is now dramatically more intelligent and easier for creators.", diff --git a/apps/frontend/src/public/news/feed/rss.xml b/apps/frontend/src/public/news/feed/rss.xml index 8be5c3172..99b913996 100644 --- a/apps/frontend/src/public/news/feed/rss.xml +++ b/apps/frontend/src/public/news/feed/rss.xml @@ -4,15 +4,23 @@ https://modrinth.com/news/ @modrinth/blog - Thu, 18 Dec 2025 20:10:25 GMT + Tue, 03 Mar 2026 00:21:22 GMT + + <![CDATA[Introducing Server Projects]]> + + https://modrinth.com/news/article/introducing-server-projects/ + https://modrinth.com/news/article/introducing-server-projects/ + Mon, 02 Mar 2026 15:00:00 GMT + <![CDATA[<p>Big news: we’re shipping our first new project type in years!</p><p>Server Projects are coming to Modrinth, and they’re not just a typical server list. They’re deeply integrated into the platform and app in ways that make playing seamless.</p><p>We genuinely believe modded is the future of large-scale multiplayer Minecraft, so let's jump in!</p><div class="video-wrapper mb-8"><video autoplay loop muted playsinline><source src="./server-discovery-in-app.mp4" type="video/mp4"></video></div><h3>TL;DR</h3><ul><li>New Server Project type</li><li>Three compatibility types: vanilla, modded (published pack), or modded (uploaded pack)</li><li>Joining a server from the app downloads the required content and launches you directly into the server</li><li>New linked server instance type that receives updates from the server</li><li>Server Projects are not eligible for payouts</li></ul><h2>Design Goals</h2><p>Let’s start with why we built this.</p><p>Most of the fun in Minecraft happens with other people, but getting into a modded multiplayer experience is still harder than it should be. We think this is the future of multiplayer for a few reasons:</p><ul><li>Modding enables far deeper experiences than server-side plugins ever will.</li><li>The real constraint has been distribution and setup. Players have to find the server, install the right content, keep it updated, and hope everything matches.</li><li>Multiplayer discovery in Minecraft has never been great. It should be easier to join a server, and just as easy to join a modded one.</li></ul><p>Additionally, modpack discovery has become noisy on Modrinth. Servers fork popular packs with small tweaks and climb discovery, which crowds out original creators.</p><h2>Project Creation</h2><p>Server Projects are different from other project types because they don’t always have uploaded files. Instead, servers define their compatibility, which can include specifying any required content.</p><p>For the initial release, we support two compatibility models: vanilla and required modpack. We also have ideas to expand this with a minimum requirements model in the future. Authors would define the required mod and version needed to join and could recommend modpacks that work as well.</p><p>When setting up your server project, you define this in the Server Compatibility section. It comes in three types:</p><ul><li>Vanilla server</li><li>Modded server (published Modrinth pack)</li><li>Modded server (uploaded custom pack)</li></ul><p>Each type defines different requirements to join. Vanilla servers specify supported and recommended Minecraft versions. Modded servers either link a Modrinth pack or upload a custom pack, which enforces the required version and mod loader.</p><div class="video-wrapper mb-8"><video autoplay loop muted playsinline><source src="./compatability-type-config.mp4" type="video/mp4"></video></div><p>Server Projects also introduce some new fields used for discovery and project pages:</p><ul><li>Banner</li><li>Country (where it is hosted)</li><li>Language</li><li>Java address</li><li>Bedrock address (not used yet)</li><li>Server compatibility</li></ul><p>Additionally, Server Projects are the only project type <strong>not eligible for payouts</strong>. They do not earn revenue from views or downloads on the project itself. Any required content they point to, such as a modpack, receives the download and associated revenue.</p><h2>Project Discovery</h2><p>Server Projects use two new discovery metrics instead of downloads to help surface new servers over time. These are:</p><ul><li><strong>Players online:</strong> The live player count reported by the server.</li><li><strong>Verified plays:</strong> Joins from the Modrinth App in the last two weeks.</li></ul><p><img src="/news/article/introducing-server-projects/project-discovery.webp" alt="Server discovery"></p><p>Server Projects also have their own set of filters to make finding the right server easier:</p><ul><li>Type (vanilla vs modded)</li><li>Features</li><li>Gameplay</li><li>Meta</li><li>Community</li><li>Game version</li><li>Country</li><li>Language</li></ul><p>Additionally, Server Projects are different from other project types because they’re live experiences. If they aren’t joinable, they don’t provide value. To keep discovery healthy, servers that aren’t pingable for a sustained period are removed from discovery.</p><h2>Joining a Server</h2><p>Joining a server is where this all comes together. While in the app, clicking play on a server triggers different flows depending on the server type:</p><ol><li>Vanilla servers immediately create a Fabric instance in the app using the recommended version set by the author.</li><li>Modded servers show a modal which displays the required content. Clicking install creates an instance with that content.</li></ol><p><img src="/news/article/introducing-server-projects/joining-a-server.webp" alt="Required content modal"></p><p>Once installation finishes, you’ll see a completion toast that, when clicked, skips the multiplayer screen and loads you directly into the server. After the initial setup, clicking play always boots straight into the server.</p><p>Additionally, if you click play from the website, we’ll deep link into the app if it’s installed.</p><h3>Linked Server Instances</h3><p>As mentioned earlier, joining a server creates an instance. These are called linked server instances and are similar to linked modpack instances.</p><p>Key differences:</p><ul><li>It’s linked to a server project, not a modpack project.</li><li>You can only add client-side mods. You can unlink it in settings to convert it into a linked modpack instance, but it will stop receiving server updates.</li><li>It always enforces the required version. If an update is available, you must accept it before launching again.</li></ul><h3>Server Project Updates</h3><p>When a server updates its compatibility, such as publishing a new modpack version, that update is distributed to all linked instances. The next time a player launches, they’re prompted to accept the changes before joining. This keeps the server and associated instances in sync.</p><p><img src="/news/article/introducing-server-projects/server-project-updates.webp" alt="Update available modal"></p><p>—</p><p>That’s all from us! Thank you so much for your continued support and happy playing!</p>]]> + <![CDATA[Streamlined Version Creation]]> https://modrinth.com/news/article/streamlined-version-creation/ https://modrinth.com/news/article/streamlined-version-creation/ - Fri, 12 Dec 2025 23:00:00 GMT + Thu, 18 Dec 2025 20:50:00 GMT <![CDATA[<p>Hey everyone! As part of our ongoing work to improve the creator side of the platform, we’re shipping a new project version creation and editing today. This part of the product was showing its age, so we’ve overhauled it to set us up for the new project types we plan to ship in the new year!</p><h2>TL;DR</h2><ul><li>Multi-file uploads with primary file detection and new supplementary file types</li><li>Automatic detection of version number, subtitle, loaders, game versions, and environment bundled into a version summary</li><li>A new loader selector that groups loaders by project type</li><li>A new game version selector with search and selecting version ranges</li><li>Project environments moved to be on a per-version basis</li><li>A new dependency selector with search and smart suggestions</li><li>Project gallery, versions, and publishing checklist moved into project settings</li></ul><h2>File uploading</h2><p>For starters, we’ve been centralizing all project editing into Project Settings to make the experience clearer and more approachable for new creators. Editing project versions now happens directly within Project Settings and projects look slightly different if you’re the creator.</p><p><img src="/news/article/streamlined-version-creation/edit-button.webp" alt="Project page header showing the primary action as &quot;Edit project&quot; for the creator"></p><p>You can create a new version by drag and dropping files into the versions table or creating a new version and uploading them. Multiple files can be uploaded at once.</p><p>The primary file is explicitly listed at the top and separate from any supplementary files. From there, you can add additional supplementary files and assign their types. Newly supported types include sources jar, dev jar, javadoc jar, and signature file.</p><div class="video-wrapper mb-8"><video autoplay loop muted playsinline><source src="https://cdn-raw.modrinth.com/blog/streamlined-version-creation/vid1.mp4" type="video/mp4"></video></div><h2>Version summary</h2><p>Once you’ve uploaded your files, you’re taken to a summary page where we automatically detect the version number, subtitle, loaders, game versions, and environments based on the primary file and previous project versions.</p><p>Any field can be individually edited by clicking the edit button in the top right. For cases where we’re unable to detect something, that field simply won’t appear in the summary and will instead show up as an additional step in the modal flow.</p><p><img src="/news/article/streamlined-version-creation/details.webp" alt="Add details stage of the upload modal, where the user selects version type, number, subtitle, and can edit loaders, game versions, and environment metadata."></p><h2>Loader selector</h2><p>We’ve added a refreshed loader selection screen that groups loaders by project type. You can click any loader tag to add it.</p><div class="video-wrapper mb-8"><video autoplay loop muted playsinline><source src="https://cdn-raw.modrinth.com/blog/streamlined-version-creation/vid2.mp4" type="video/mp4"></video></div><h2>Game version selector</h2><p>Game versions now have their own dedicated step. This was a major pain point for projects that support a wide range of game versions. You can search for versions or toggle between releases and snapshots. Select individual versions with a click, or use shift-click to select a range.</p><div class="video-wrapper mb-8"><video autoplay loop muted playsinline><source src="https://cdn-raw.modrinth.com/blog/streamlined-version-creation/vid3.mp4" type="video/mp4"></video></div><h2>Environment selector</h2><p>Project environments were released earlier this year, and we heard feedback that some projects need them configured at the version level. We’ve moved environments out of project settings and into versions. For the vast majority of projects environments rarely change, so we automatically carry them over from a previous version that uses the same loader. You can always edit this if needed.</p><p><img src="/news/article/streamlined-version-creation/environments.webp" alt="Edit environment screen, showing a bunch of options to select such as client-side only, server-side only, and more."></p><h2>Dependency selector</h2><p>Dependencies were another pain point, so we’ve added the ability to search projects and versions directly, no more copying IDs. We also suggest dependencies from the other versions you’ve uploaded with the same loader, making them easy to add with a single click.</p><div class="video-wrapper mb-8"><video autoplay loop muted playsinline><source src="https://cdn-raw.modrinth.com/blog/streamlined-version-creation/vid4.mp4" type="video/mp4"></video></div><h2>Misc</h2><ul><li>Gallery management has now also been moved into Project Settings</li><li>The project publishing checklist now lives in Project Settings</li></ul><hr><p>Thank you all for your continued support. We hope you have a great holiday and get some well-earned time with your families! 🎅</p>]]> diff --git a/packages/assets/generated-icons.ts b/packages/assets/generated-icons.ts index ea1d254f2..8c77ae736 100644 --- a/packages/assets/generated-icons.ts +++ b/packages/assets/generated-icons.ts @@ -3,6 +3,8 @@ import type { FunctionalComponent, SVGAttributes } from 'vue' +export type IconComponent = FunctionalComponent + import _AffiliateIcon from './icons/affiliate.svg?component' import _AlignLeftIcon from './icons/align-left.svg?component' import _ArchiveIcon from './icons/archive.svg?component' @@ -378,8 +380,6 @@ import _XCircleIcon from './icons/x-circle.svg?component' import _ZoomInIcon from './icons/zoom-in.svg?component' import _ZoomOutIcon from './icons/zoom-out.svg?component' -export type IconComponent = FunctionalComponent - export const AffiliateIcon = _AffiliateIcon export const AlignLeftIcon = _AlignLeftIcon export const ArchiveIcon = _ArchiveIcon diff --git a/packages/blog/articles/introducing-server-projects.md b/packages/blog/articles/introducing-server-projects.md new file mode 100644 index 000000000..fe32674ae --- /dev/null +++ b/packages/blog/articles/introducing-server-projects.md @@ -0,0 +1,124 @@ +--- +title: Introducing Server Projects +summary: A new project type made for seamless modded multiplayer on Modrinth. +date: 2026-03-02T15:00:00+00:00 +authors: ['AJfd8YH6', '6EjnV9Uf', 'xSQqYYIN'] +--- + +Big news: we’re shipping our first new project type in years! + +Server Projects are coming to Modrinth, and they’re not just a typical server list. They’re deeply integrated into the platform and app in ways that make playing seamless. + +We genuinely believe modded is the future of large-scale multiplayer Minecraft, so let's jump in! + +
+ +
+ +### TL;DR + +- New Server Project type +- Three compatibility types: vanilla, modded (published pack), or modded (uploaded pack) +- Joining a server from the app downloads the required content and launches you directly into the server +- New linked server instance type that receives updates from the server +- Server Projects are not eligible for payouts + +## Design Goals + +Let’s start with why we built this. + +Most of the fun in Minecraft happens with other people, but getting into a modded multiplayer experience is still harder than it should be. We think this is the future of multiplayer for a few reasons: + +- Modding enables far deeper experiences than server-side plugins ever will. +- The real constraint has been distribution and setup. Players have to find the server, install the right content, keep it updated, and hope everything matches. +- Multiplayer discovery in Minecraft has never been great. It should be easier to join a server, and just as easy to join a modded one. + +Additionally, modpack discovery has become noisy on Modrinth. Servers fork popular packs with small tweaks and climb discovery, which crowds out original creators. + +## Project Creation + +Server Projects are different from other project types because they don’t always have uploaded files. Instead, servers define their compatibility, which can include specifying any required content. + +For the initial release, we support two compatibility models: vanilla and required modpack. We also have ideas to expand this with a minimum requirements model in the future. Authors would define the required mod and version needed to join and could recommend modpacks that work as well. + +When setting up your server project, you define this in the Server Compatibility section. It comes in three types: + +- Vanilla server +- Modded server (published Modrinth pack) +- Modded server (uploaded custom pack) + +Each type defines different requirements to join. Vanilla servers specify supported and recommended Minecraft versions. Modded servers either link a Modrinth pack or upload a custom pack, which enforces the required version and mod loader. + +
+ +
+ +Server Projects also introduce some new fields used for discovery and project pages: + +- Banner +- Country (where it is hosted) +- Language +- Java address +- Bedrock address (not used yet) +- Server compatibility + +Additionally, Server Projects are the only project type **not eligible for payouts**. They do not earn revenue from views or downloads on the project itself. Any required content they point to, such as a modpack, receives the download and associated revenue. + +## Project Discovery + +Server Projects use two new discovery metrics instead of downloads to help surface new servers over time. These are: + +- **Players online:** The live player count reported by the server. +- **Verified plays:** Joins from the Modrinth App in the last two weeks. + +![Server discovery](./project-discovery.webp) + +Server Projects also have their own set of filters to make finding the right server easier: + +- Type (vanilla vs modded) +- Features +- Gameplay +- Meta +- Community +- Game version +- Country +- Language + +Additionally, Server Projects are different from other project types because they’re live experiences. If they aren’t joinable, they don’t provide value. To keep discovery healthy, servers that aren’t pingable for a sustained period are removed from discovery. + +## Joining a Server + +Joining a server is where this all comes together. While in the app, clicking play on a server triggers different flows depending on the server type: + +1. Vanilla servers immediately create a Fabric instance in the app using the recommended version set by the author. +2. Modded servers show a modal which displays the required content. Clicking install creates an instance with that content. + +![Required content modal](./joining-a-server.webp) + +Once installation finishes, you’ll see a completion toast that, when clicked, skips the multiplayer screen and loads you directly into the server. After the initial setup, clicking play always boots straight into the server. + +Additionally, if you click play from the website, we’ll deep link into the app if it’s installed. + +### Linked Server Instances + +As mentioned earlier, joining a server creates an instance. These are called linked server instances and are similar to linked modpack instances. + +Key differences: + +- It’s linked to a server project, not a modpack project. +- You can only add client-side mods. You can unlink it in settings to convert it into a linked modpack instance, but it will stop receiving server updates. +- It always enforces the required version. If an update is available, you must accept it before launching again. + +### Server Project Updates + +When a server updates its compatibility, such as publishing a new modpack version, that update is distributed to all linked instances. The next time a player launches, they’re prompted to accept the changes before joining. This keeps the server and associated instances in sync. + +![Update available modal](./server-project-updates.webp) + +— + +That’s all from us! Thank you so much for your continued support and happy playing! diff --git a/packages/blog/compiled/index.ts b/packages/blog/compiled/index.ts index a10664932..5485f5b08 100644 --- a/packages/blog/compiled/index.ts +++ b/packages/blog/compiled/index.ts @@ -11,6 +11,7 @@ import { article as creator_withdrawals_overhaul } from "./creator_withdrawals_o import { article as design_refresh } from "./design_refresh"; import { article as download_adjustment } from "./download_adjustment"; import { article as free_server_medal } from "./free_server_medal"; +import { article as introducing_server_projects } from "./introducing_server_projects"; import { article as knossos_v2_1_0 } from "./knossos_v2_1_0"; import { article as licensing_guide } from "./licensing_guide"; import { article as modpack_changes } from "./modpack_changes"; @@ -47,6 +48,7 @@ export const articles = [ design_refresh, download_adjustment, free_server_medal, + introducing_server_projects, knossos_v2_1_0, licensing_guide, modpack_changes, diff --git a/packages/blog/compiled/introducing_server_projects.content.ts b/packages/blog/compiled/introducing_server_projects.content.ts new file mode 100644 index 000000000..c7b954511 --- /dev/null +++ b/packages/blog/compiled/introducing_server_projects.content.ts @@ -0,0 +1,2 @@ +// AUTO-GENERATED FILE - DO NOT EDIT +export const html = `

Big news: we’re shipping our first new project type in years!

Server Projects are coming to Modrinth, and they’re not just a typical server list. They’re deeply integrated into the platform and app in ways that make playing seamless.

We genuinely believe modded is the future of large-scale multiplayer Minecraft, so let's jump in!

TL;DR

  • New Server Project type
  • Three compatibility types: vanilla, modded (published pack), or modded (uploaded pack)
  • Joining a server from the app downloads the required content and launches you directly into the server
  • New linked server instance type that receives updates from the server
  • Server Projects are not eligible for payouts

Design Goals

Let’s start with why we built this.

Most of the fun in Minecraft happens with other people, but getting into a modded multiplayer experience is still harder than it should be. We think this is the future of multiplayer for a few reasons:

  • Modding enables far deeper experiences than server-side plugins ever will.
  • The real constraint has been distribution and setup. Players have to find the server, install the right content, keep it updated, and hope everything matches.
  • Multiplayer discovery in Minecraft has never been great. It should be easier to join a server, and just as easy to join a modded one.

Additionally, modpack discovery has become noisy on Modrinth. Servers fork popular packs with small tweaks and climb discovery, which crowds out original creators.

Project Creation

Server Projects are different from other project types because they don’t always have uploaded files. Instead, servers define their compatibility, which can include specifying any required content.

For the initial release, we support two compatibility models: vanilla and required modpack. We also have ideas to expand this with a minimum requirements model in the future. Authors would define the required mod and version needed to join and could recommend modpacks that work as well.

When setting up your server project, you define this in the Server Compatibility section. It comes in three types:

  • Vanilla server
  • Modded server (published Modrinth pack)
  • Modded server (uploaded custom pack)

Each type defines different requirements to join. Vanilla servers specify supported and recommended Minecraft versions. Modded servers either link a Modrinth pack or upload a custom pack, which enforces the required version and mod loader.

Server Projects also introduce some new fields used for discovery and project pages:

  • Banner
  • Country (where it is hosted)
  • Language
  • Java address
  • Bedrock address (not used yet)
  • Server compatibility

Additionally, Server Projects are the only project type not eligible for payouts. They do not earn revenue from views or downloads on the project itself. Any required content they point to, such as a modpack, receives the download and associated revenue.

Project Discovery

Server Projects use two new discovery metrics instead of downloads to help surface new servers over time. These are:

  • Players online: The live player count reported by the server.
  • Verified plays: Joins from the Modrinth App in the last two weeks.

Server discovery

Server Projects also have their own set of filters to make finding the right server easier:

  • Type (vanilla vs modded)
  • Features
  • Gameplay
  • Meta
  • Community
  • Game version
  • Country
  • Language

Additionally, Server Projects are different from other project types because they’re live experiences. If they aren’t joinable, they don’t provide value. To keep discovery healthy, servers that aren’t pingable for a sustained period are removed from discovery.

Joining a Server

Joining a server is where this all comes together. While in the app, clicking play on a server triggers different flows depending on the server type:

  1. Vanilla servers immediately create a Fabric instance in the app using the recommended version set by the author.
  2. Modded servers show a modal which displays the required content. Clicking install creates an instance with that content.

Required content modal

Once installation finishes, you’ll see a completion toast that, when clicked, skips the multiplayer screen and loads you directly into the server. After the initial setup, clicking play always boots straight into the server.

Additionally, if you click play from the website, we’ll deep link into the app if it’s installed.

Linked Server Instances

As mentioned earlier, joining a server creates an instance. These are called linked server instances and are similar to linked modpack instances.

Key differences:

  • It’s linked to a server project, not a modpack project.
  • You can only add client-side mods. You can unlink it in settings to convert it into a linked modpack instance, but it will stop receiving server updates.
  • It always enforces the required version. If an update is available, you must accept it before launching again.

Server Project Updates

When a server updates its compatibility, such as publishing a new modpack version, that update is distributed to all linked instances. The next time a player launches, they’re prompted to accept the changes before joining. This keeps the server and associated instances in sync.

Update available modal

That’s all from us! Thank you so much for your continued support and happy playing!

`; diff --git a/packages/blog/compiled/introducing_server_projects.ts b/packages/blog/compiled/introducing_server_projects.ts new file mode 100644 index 000000000..5ee1206ab --- /dev/null +++ b/packages/blog/compiled/introducing_server_projects.ts @@ -0,0 +1,12 @@ +// AUTO-GENERATED FILE - DO NOT EDIT +export const article = { + html: () => import(`./introducing_server_projects.content`).then(m => m.html), + title: "Introducing Server Projects", + summary: "A new project type made for seamless modded multiplayer on Modrinth.", + date: "2026-03-02T15:00:00.000Z", + slug: "introducing-server-projects", + authors: ["AJfd8YH6","6EjnV9Uf","xSQqYYIN"], + unlisted: false, + thumbnail: true, + +}; diff --git a/packages/blog/public/introducing-server-projects/compatability-type-config.mp4 b/packages/blog/public/introducing-server-projects/compatability-type-config.mp4 new file mode 100644 index 000000000..7ddd50f61 Binary files /dev/null and b/packages/blog/public/introducing-server-projects/compatability-type-config.mp4 differ diff --git a/packages/blog/public/introducing-server-projects/joining-a-server.webp b/packages/blog/public/introducing-server-projects/joining-a-server.webp new file mode 100644 index 000000000..d4f7061b2 Binary files /dev/null and b/packages/blog/public/introducing-server-projects/joining-a-server.webp differ diff --git a/packages/blog/public/introducing-server-projects/project-discovery.webp b/packages/blog/public/introducing-server-projects/project-discovery.webp new file mode 100644 index 000000000..384168261 Binary files /dev/null and b/packages/blog/public/introducing-server-projects/project-discovery.webp differ diff --git a/packages/blog/public/introducing-server-projects/server-discovery-in-app.mp4 b/packages/blog/public/introducing-server-projects/server-discovery-in-app.mp4 new file mode 100644 index 000000000..6e476ab1b Binary files /dev/null and b/packages/blog/public/introducing-server-projects/server-discovery-in-app.mp4 differ diff --git a/packages/blog/public/introducing-server-projects/server-project-updates.webp b/packages/blog/public/introducing-server-projects/server-project-updates.webp new file mode 100644 index 000000000..e17f79486 Binary files /dev/null and b/packages/blog/public/introducing-server-projects/server-project-updates.webp differ diff --git a/packages/blog/public/introducing-server-projects/thumbnail.webp b/packages/blog/public/introducing-server-projects/thumbnail.webp new file mode 100644 index 000000000..d6e7aff66 Binary files /dev/null and b/packages/blog/public/introducing-server-projects/thumbnail.webp differ diff --git a/packages/utils/parse.ts b/packages/utils/parse.ts index 4011141c8..d981d07b2 100644 --- a/packages/utils/parse.ts +++ b/packages/utils/parse.ts @@ -1,5 +1,8 @@ import MarkdownIt from 'markdown-it' -import { escapeAttrValue, FilterXSS, safeAttrValue, whiteList } from 'xss' +import xss from 'xss' + +// @ts-expect-error xss types don't reflect CJS default export shape +const { escapeAttrValue, FilterXSS, safeAttrValue, whiteList } = xss export const configuredXss = new FilterXSS({ whiteList: {