diff --git a/docs/public/manifest.webmanifest b/docs/public/manifest.webmanifest index 1812faee..811dac1f 100644 --- a/docs/public/manifest.webmanifest +++ b/docs/public/manifest.webmanifest @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/web-manifest", "name": "The PWA Plugin for Next.js", - "short_name": "Next PWA", + "short_name": "next-pwa", "theme_color": "#171717", "background_color": "#171717", "display": "fullscreen", diff --git a/docs/src/app/(home)/components.tsx b/docs/src/app/(home)/components.tsx index 3d189d82..1ecddc15 100644 --- a/docs/src/app/(home)/components.tsx +++ b/docs/src/app/(home)/components.tsx @@ -12,8 +12,8 @@ export const CodeShowcase = ({ const [code, ...others] = children; return (
-
span]:mt-0")}>{others}
-
{code}
+
span]:mt-0")}>{others}
+
{code}
); }; diff --git a/docs/src/app/(home)/constants.ts b/docs/src/app/(home)/constants.ts deleted file mode 100644 index 45e02193..00000000 --- a/docs/src/app/(home)/constants.ts +++ /dev/null @@ -1,33 +0,0 @@ -interface Feature { - icon: string; - label: string; - description: string; -} - -export const FEATURES_LIST: Feature[] = [ - { - icon: "✊", - label: "Zero-config", - description: "No configuration needed to get started...", - }, - { - icon: "⛏️", - label: "Configurable", - description: "...yet there are many options available to extend the plugin.", - }, - { - icon: "💯", - label: "Fast", - description: "Blow your user's mind with a website as fast as lightning ⚡", - }, - { - icon: "🔌", - label: "Offline", - description: "Proper offline support. For both App and Pages Router.", - }, - { - icon: "🚀", - label: "Developer experience", - description: "Built-in TypeScript definitions and JSDoc to enable the best DX.", - }, -]; diff --git a/docs/src/app/(home)/page.tsx b/docs/src/app/(home)/page.tsx index 97102bc7..fedf0c05 100644 --- a/docs/src/app/(home)/page.tsx +++ b/docs/src/app/(home)/page.tsx @@ -14,7 +14,6 @@ import { clsx } from "@/utils/clsx.js"; import { rehypePlugins, remarkPlugins } from "../../../contentlayer.constants.js"; import { CodeShowcase } from "./components.js"; -import { FEATURES_LIST } from "./constants.js"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -33,23 +32,28 @@ const Page = async () => { const RenderedCodeShowcase = getMDXComponent(compiledText.code); return ( -
-
+
div]:max-w-screen-lg [&>div]:md:self-center", + inter.className, + )} + > +

- Make performant web apps with Next.js & PWA. + Create progressive web apps with Next.js.

-

+

next-pwa enables you to create PWAs with Next.js. No configuration needed, yet so configurable.

{ > Get started - npx create-next-app -e https://github.com/DuCanhGH/next-pwa/tree/master/examples/basic
-
-
- {FEATURES_LIST.map((feature, idx) => ( -
-

- {feature.icon} {feature.label} -

-

{feature.description}

-
- ))} -
-
-
+
allDocs.map((post) => ({ slug: post._raw.flattenedPath.split("/") })); @@ -36,7 +36,7 @@ const PostLayout: PageComponent = async ({ params }) => {

On This Page

- +
-
+
diff --git a/docs/src/app/docs/not-found.tsx b/docs/src/app/docs/not-found.tsx index 0727a05f..b8ad6030 100644 --- a/docs/src/app/docs/not-found.tsx +++ b/docs/src/app/docs/not-found.tsx @@ -1,5 +1,5 @@ import { Heading } from "@/components/Heading.js"; -const NotFound = () => Page not found.; +const NotFound = () => Page not found.; export default NotFound; diff --git a/docs/src/app/docs/opengraph-image.ts b/docs/src/app/docs/opengraph-image.ts index 1477152c..75d3f72e 100644 --- a/docs/src/app/docs/opengraph-image.ts +++ b/docs/src/app/docs/opengraph-image.ts @@ -1,6 +1,6 @@ import { generateOGImage } from "@/utils/generateOGImage.js"; -export const alt = "Next PWA - Docs"; +export const alt = "next-pwa - Docs"; export const size = { width: 1200, height: 600, diff --git a/docs/src/app/globals.css b/docs/src/app/globals.css index 5a46efb8..453beca9 100644 --- a/docs/src/app/globals.css +++ b/docs/src/app/globals.css @@ -26,6 +26,19 @@ html[data-theme="dark"] .shiki span:not([class^="twoslash-"]) { body { @apply box-border bg-neutral-50 transition-colors duration-100 dark:bg-neutral-950; } + h1, + h2, + h3, + h4, + h5, + h6, + blockquote { + @apply text-balance break-words; + } + p, + video { + @apply my-3; + } details > summary { @apply cursor-pointer select-none list-none; @@ -66,6 +79,27 @@ html[data-theme="dark"] .shiki span:not([class^="twoslash-"]) { .text-toc.active { @apply xl:text-primary-light xl:dark:text-primary-dark; } + .text-comment { + @apply text-neutral-600 dark:text-neutral-400; + } + .heading.h1 { + @apply text-4xl font-semibold leading-10 tracking-tight mb-6; + } + .heading.h2 { + @apply text-3xl font-semibold leading-10 tracking-tight mb-3 mt-6; + } + .heading.h3 { + @apply text-2xl font-semibold leading-7 tracking-tight my-3; + } + .heading.h4 { + @apply text-xl font-medium leading-5 tracking-tight my-3; + } + .heading.default { + @apply text-black dark:text-white; + } + .heading.error { + @apply text-red-500 dark:text-red-400; + } } @media (prefers-reduced-motion) { diff --git a/docs/src/app/layout.tsx b/docs/src/app/layout.tsx index 5d2d101c..e5ae466e 100644 --- a/docs/src/app/layout.tsx +++ b/docs/src/app/layout.tsx @@ -18,27 +18,27 @@ export const metadata: Metadata = { }, referrer: "no-referrer", title: { - default: "Next PWA", - template: "%s - Next PWA", + default: "next-pwa", + template: "%s - next-pwa", }, description: "Make performant web apps with Next.js & PWA.", - applicationName: "Next PWA", + applicationName: "next-pwa", manifest: "/manifest.webmanifest", authors: [{ name: "DuCanhGH", url: "https://github.com/DuCanhGH/" }], keywords: "react, pwa, service-worker, progressive-web-app, nextjs, next.js, workbox", openGraph: { type: "website", title: { - default: "Next PWA", - template: "%s - Next PWA", + default: "next-pwa", + template: "%s - next-pwa", }, description: "Make performant web apps with Next.js & PWA.", }, twitter: { card: "summary_large_image", title: { - default: "Next PWA", - template: "%s - Next PWA", + default: "next-pwa", + template: "%s - next-pwa", }, description: "Make performant web apps with Next.js & PWA.", }, diff --git a/docs/src/app/opengraph-image.ts b/docs/src/app/opengraph-image.ts index 9c377ac2..b43b3dd1 100644 --- a/docs/src/app/opengraph-image.ts +++ b/docs/src/app/opengraph-image.ts @@ -1,6 +1,6 @@ import { generateOGImage } from "@/utils/generateOGImage.js"; -export const alt = "Next PWA"; +export const alt = "next-pwa"; export const size = { width: 1200, height: 600, diff --git a/docs/src/app/~offline/ReloadButton.tsx b/docs/src/app/~offline/ReloadButton.tsx index 9ec7d0ab..0fb5d267 100644 --- a/docs/src/app/~offline/ReloadButton.tsx +++ b/docs/src/app/~offline/ReloadButton.tsx @@ -4,7 +4,7 @@ import { Heading } from "@/components/Heading"; export const ReloadButton = () => { return ( ); }; diff --git a/docs/src/app/~offline/page.tsx b/docs/src/app/~offline/page.tsx index 229694c6..77c3ba6d 100644 --- a/docs/src/app/~offline/page.tsx +++ b/docs/src/app/~offline/page.tsx @@ -5,7 +5,7 @@ import { ReloadButton } from "./ReloadButton.js"; const Page = () => { return (
- offline. + offline.
); diff --git a/docs/src/components/ActiveBox.tsx b/docs/src/components/ActiveBox.tsx index cd4e0a79..eb666fba 100644 --- a/docs/src/components/ActiveBox.tsx +++ b/docs/src/components/ActiveBox.tsx @@ -4,9 +4,9 @@ import type { DetailedHTMLProps, HTMLAttributes } from "react"; import { clsx } from "@/utils/clsx"; -const baseActiveBoxClassName = "items-center justify-between gap-2 text-left w-full flex rounded text-sm transition-colors [word-break:break-word] font-medium"; -const hoverActiveBoxClassName = - "text-black dark:text-white hover:bg-neutral-200 hover:text-black dark:hover:bg-neutral-800 dark:hover:text-white"; +const baseActiveBoxClassName = + "items-center justify-between gap-2 text-left w-full flex rounded text-sm transition-colors [word-break:break-word] font-medium"; +const hoverActiveBoxClassName = "text-black dark:text-white hover:bg-neutral-200 hover:text-black dark:hover:bg-neutral-800 dark:hover:text-white"; const activeActiveBoxClassName = "bg-neutral-200 text-black dark:bg-neutral-800 dark:text-white"; export interface ActiveBoxProps extends DetailedHTMLProps, HTMLDivElement> { diff --git a/docs/src/components/GitHubLogo.tsx b/docs/src/components/GitHubLogo.tsx index e137334c..5e86ed87 100644 --- a/docs/src/components/GitHubLogo.tsx +++ b/docs/src/components/GitHubLogo.tsx @@ -1,8 +1,6 @@ import type { SVGProps } from "react"; -export const GitHubLogo = ( - props: Omit, "ref" | "viewBox" | "xmlns"> -) => ( +export const GitHubLogo = (props: Omit, "ref" | "viewBox" | "xmlns">) => ( GitHub diff --git a/docs/src/components/Heading.tsx b/docs/src/components/Heading.tsx index 6f3be27b..dbaf876f 100644 --- a/docs/src/components/Heading.tsx +++ b/docs/src/components/Heading.tsx @@ -1,54 +1,19 @@ -import type { DetailedHTMLProps, ElementType, HTMLAttributes } from "react"; +import type { DetailedHTMLProps, HTMLAttributes } from "react"; import { forwardRef } from "react"; -import { twMerge } from "tailwind-merge"; import { clsx } from "@/utils/clsx.js"; -export interface HeadingProps extends DetailedHTMLProps, HTMLParagraphElement> { +export interface HeadingProps extends Omit, HTMLParagraphElement>, "className"> { variant?: "default" | "error"; - type?: "subtitle" | "title" | "title-large" | "display"; + type?: "h4" | "h3" | "h2" | "h1"; isInSatori?: boolean; } -const mapTypeToComponent: Record< - NonNullable, - { - element: ElementType; - className?: string; - } -> = { - subtitle: { - element: "h4", - className: "font-semibold tracking-tight my-8 text-xl", - }, - title: { - element: "h3", - className: "font-semibold tracking-tight my-8 text-2xl", - }, - "title-large": { - element: "h2", - className: "font-semibold tracking-tight my-10 pb-1 text-3xl", - }, - display: { - element: "h1", - className: "font-bold tracking-tight my-2 text-4xl", - }, -}; - -export const Heading = forwardRef(({ id, variant = "default", className, type = "title", ...rest }, ref) => { - const mappedComponent = mapTypeToComponent[type]; - const Component = mappedComponent.element; +export const Heading = forwardRef(({ id, variant = "default", type = "h2", ...rest }, ref) => { + const Component = type; return ( - - + + {id && (

diff --git a/docs/src/components/Tabs.tsx b/docs/src/components/Tabs.tsx index c05e136b..af0f0eed 100644 --- a/docs/src/components/Tabs.tsx +++ b/docs/src/components/Tabs.tsx @@ -1,6 +1,6 @@ "use client"; import { clsx } from "@/utils/clsx"; -import { useState, type ReactElement, useId } from "react"; +import { type ReactElement, useId, useState } from "react"; export const Tabs = ({ titles, children }: { titles: string[]; children: ReactElement | ReactElement[] }) => { const [currentIndex, setCurrentIndex] = useState(0); @@ -13,23 +13,24 @@ export const Tabs = ({ titles, children }: { titles: string[]; children: ReactEl

- {titles.map((t, idx) => { + {titles.map((tab, idx) => { const isActive = idx === currentIndex; return (
- {codes.map((e, idx) => { + {codes.map((code, idx) => { const isActive = idx === currentIndex; return (
- {isActive && e} + {isActive && code}
); })} diff --git a/docs/src/shared/TocContext.tsx b/docs/src/shared/TocContext.tsx index 0a9e5945..243cae21 100644 --- a/docs/src/shared/TocContext.tsx +++ b/docs/src/shared/TocContext.tsx @@ -2,7 +2,7 @@ import { Heading, type HeadingProps } from "@/components/Heading"; import { clsx } from "@/utils/clsx"; import Link from "next/link"; -import { type ReactNode, createContext, useEffect, useState, type DetailedHTMLProps, type AnchorHTMLAttributes, use, useRef, act } from "react"; +import { type AnchorHTMLAttributes, type DetailedHTMLProps, type ReactNode, act, createContext, use, useEffect, useRef, useState } from "react"; interface TocContextProperties { activeId: Set; diff --git a/docs/src/shared/mdxComponents.tsx b/docs/src/shared/mdxComponents.tsx index 92a0c2bb..ec97f27b 100644 --- a/docs/src/shared/mdxComponents.tsx +++ b/docs/src/shared/mdxComponents.tsx @@ -9,11 +9,9 @@ import { AnchorLinkUnderline } from "@/components/Link/AnchorLinkUnderline.js"; import { LinkUnderline } from "@/components/Link/LinkUnderline.js"; import { Tabs } from "@/components/Tabs.js"; import { Text } from "@/components/Text.js"; -import { clsx } from "@/utils/clsx.js"; import { TocHeading, TocLink } from "./TocContext"; const TEXT_COLOR = "text-black dark:text-white"; -const TEXT_BORDER = "border-b border-neutral-200/70 dark:border-neutral-400/10"; const filterLegacyRef = (ref: LegacyRef | undefined) => (typeof ref === "string" ? undefined : ref); @@ -44,11 +42,11 @@ export const mdxComponents: MDXComponents = { return ; }, - p: ({ ref, className, ...rest }) => , - h1: ({ ref, ...rest }) => , - h2: ({ className, ref, ...rest }) => , - h3: ({ ref, ...rest }) => , - h4: ({ ref, ...rest }) => , + p: ({ ref, ...rest }) => , + h1: ({ ref, ...rest }) => , + h2: ({ className, ref, ...rest }) => , + h3: ({ ref, ...rest }) => , + h4: ({ ref, ...rest }) => , code: ({ children, ref, ...rest }) => { if (typeof children === "string") { return ( @@ -69,10 +67,10 @@ export const mdxComponents: MDXComponents = { export const tocHeadingMdxComponents: MDXComponents = { ...mdxComponents, - h1: ({ ref, ...rest }) => , - h2: ({ className, ref, ...rest }) => , - h3: ({ ref, ...rest }) => , - h4: ({ ref, ...rest }) => , + h1: ({ ref, ...rest }) => , + h2: ({ className, ref, ...rest }) => , + h3: ({ ref, ...rest }) => , + h4: ({ ref, ...rest }) => , }; export const tocMdxComponents: MDXComponents = { diff --git a/examples/custom-server/README.md b/examples/custom-server/README.md index 675d77d9..6b1d03f3 100644 --- a/examples/custom-server/README.md +++ b/examples/custom-server/README.md @@ -1,6 +1,6 @@ # next-pwa - custom server -This example demonstrates how to use serve a Next PWA with custom server. +This example demonstrates how to use serve a Next.js PWA with a custom server. It uses `fastify` as a custom server to serve `sw.js` and `precache` scripts statically, and it contains a minimal icon set and a `manifest.json` in the `public` directory. The example also features full offline support and boasts full (all 100) scores on Lighthouse 🎉. diff --git a/package.json b/package.json index c349e284..e6c5810c 100644 --- a/package.json +++ b/package.json @@ -4,13 +4,7 @@ "license": "MIT", "private": true, "packageManager": "pnpm@9.0.6", - "workspaces": [ - "docs", - "packages/**", - "examples/**", - "!**/.next", - "next-pwa-e2e-test" - ], + "workspaces": ["docs", "packages/**", "examples/**", "!**/.next", "next-pwa-e2e-test"], "scripts": { "build": "FORCE_COLOR=1 turbo run build --filter='./packages/*'", "code-check": "biome check --max-diagnostics=150 --log-kind=compact .", diff --git a/packages/next-pwa/package.json b/packages/next-pwa/package.json index c2495709..a3837624 100644 --- a/packages/next-pwa/package.json +++ b/packages/next-pwa/package.json @@ -4,22 +4,13 @@ "type": "module", "private": false, "description": "PWA for Next.js, powered by Workbox.", - "keywords": [ - "nextjs", - "pwa", - "workbox", - "web", - "service-worker" - ], + "keywords": ["nextjs", "pwa", "workbox", "web", "service-worker"], "author": "ShadowWalker , DuCanhGH", "license": "MIT", "repository": "https://github.com/DuCanhGH/next-pwa", "bugs": "https://github.com/DuCanhGH/next-pwa/issues", "homepage": "https://ducanh-next-pwa.vercel.app", - "files": [ - "dist", - "!dist/dts" - ], + "files": ["dist", "!dist/dts"], "source": "./src/index.ts", "imports": { "#utils/*.js": "./src/utils/*.ts" @@ -49,9 +40,7 @@ "types": "./dist/index.d.ts", "typesVersions": { "*": { - "workbox": [ - "./dist/sw-entry.d.ts" - ] + "workbox": ["./dist/sw-entry.d.ts"] } }, "scripts": { diff --git a/packages/next-pwa/src/index.ts b/packages/next-pwa/src/index.ts index d94fffc8..c2cf2d89 100644 --- a/packages/next-pwa/src/index.ts +++ b/packages/next-pwa/src/index.ts @@ -1,5 +1,5 @@ -import path from "node:path"; import fs from "node:fs"; +import path from "node:path"; import fg from "fast-glob"; import type { NextConfig } from "next";