Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions babel.config.cjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,10 +9,10 @@ module.exports = {
[
"babel-plugin-jsx-dom-expressions",
{
moduleName: "solid-js/web",
moduleName: "@solidjs/web",
contextToCustomElements: true,
wrapConditionals: true,
builtIns: ["For", "Show", "Switch", "Match", "Suspense", "SuspenseList", "Portal"]
builtIns: ["For", "Show", "Switch", "Match", "Loading", "Errored", "Portal"]
}
]
]
Expand Down
17 changes: 9 additions & 8 deletions package.json
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
{
"name": "@solidjs/meta",
"description": "Write meta tags to the document head",
"version": "0.29.7",
"version": "0.30.0-next.0",
"author": "Ryan Carniato",
"license": "MIT",
"repository": {
Expand DownExpand Up@@ -35,7 +35,8 @@
"release": "pnpm build && changeset publish"
},
"peerDependencies": {
"solid-js": ">=1.8.4"
"solid-js": ">=2.0.0-beta.0 <2.0.0",
"@solidjs/web": ">=2.0.0-beta.0 <2.0.0"
},
"devDependencies": {
"@babel/cli": "^7.27.0",
Expand All@@ -44,15 +45,15 @@
"@babel/preset-typescript": "7.27.0",
"@changesets/cli": "^2.28.1",
"@rollup/plugin-babel": "^6.0.4",
"@solidjs/web": "2.0.0-beta.14",
"@testing-library/jest-dom": "^6.6.3",
"@types/jest": "^29.5.14",
"@vitest/browser": "^3.1.1",
"babel-preset-solid": "^1.9.5",
"@vitest/browser": "^4.1.9",
"babel-preset-solid": "2.0.0-beta.14",
"jsdom": "^26.0.0",
"rimraf": "^6.0.1",
"solid-js": "^1.9.5",
"solid-js": "2.0.0-beta.14",
"typescript": "5.8.3",
"vite-plugin-solid": "^2.11.6",
"vitest": "^3.1.1"
"vite-plugin-solid": "^3.0.0-next.5",
"vitest": "^4.1.9"
}
}
1,039 changes: 391 additions & 648 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions pnpm-workspace.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
allowBuilds:
esbuild: true
26 changes: 13 additions & 13 deletions src/index.tsx
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
import {
Component,
type Component,
createContext,
createRenderEffect,
createUniqueId,
JSX,
onCleanup,
ParentComponent,
type ParentComponent,
sharedConfig,
useContext
} from "solid-js";
import { escape, isServer, spread, ssr, useAssets} from "solid-js/web";
import { escape, isServer, spread, ssr, useAssets, type JSX } from "@solidjs/web";

export const MetaContext = createContext<MetaContextType>();

Expand DownExpand Up@@ -58,7 +56,7 @@ const getTagKey = (tag: TagDescription, properties: string[]) => {
};

function initClientProvider() {
if (!sharedConfig.context) {
if (!sharedConfig.hydrating) {
const ssrTags = document.head.querySelectorAll(`[data-sm]`);
// `forEach` on `NodeList` is not supported in Googlebot, so use a workaround
Array.prototype.forEach.call(ssrTags, (ssrTag: Node) => ssrTag.parentNode!.removeChild(ssrTag));
Expand DownExpand Up@@ -192,15 +190,15 @@ function initServerProvider() {
tags.push(tagDesc);
return tags.length;
},
removeTag(tag: TagDescription, index: number) {}
removeTag(_tag: TagDescription, _index: number) {}
};
}

export const MetaProvider: ParentComponent = props => {
const actions = !isServer
? initClientProvider()
: initServerProvider();
return <MetaContext.Provider value={actions!}>{props.children}</MetaContext.Provider>;
return <MetaContext value={actions!}>{props.children}</MetaContext>;
};

const MetaTag = (
Expand All@@ -223,12 +221,14 @@ const MetaTag = (

export function useHead(tagDesc: TagDescription) {
const c = useContext(MetaContext);
if (!c) throw new Error("<MetaProvider /> should be in the tree");

createRenderEffect(() => {
const index = c!.addTag(tagDesc);
onCleanup(() => c!.removeTag(tagDesc, index));
});
createRenderEffect(
() => tagDesc,
tag => {
const index = c.addTag(tag);
return () => c.removeTag(tag, index);
}
);
}

function renderTags(tags: Array<TagDescription>) {
Expand Down
31 changes: 22 additions & 9 deletions test/index.spec.tsx
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
/* @jsxImportSource solid-js */
import { createSignal, getOwner, lazy } from "solid-js";
import { hydrate, render, Show } from "solid-js/web";
import { createSignal, flush, getOwner, lazy, Loading, Show } from "solid-js";
import { hydrate, render } from "@solidjs/web";
import { MetaProvider, Title, Style, Meta, Link, Base } from "../src";
import { hydrationScript, removeScript } from "./hydration_script";
import { describe, test, expect, beforeEach, afterEach } from "vitest";
import { test, expect, beforeEach, afterEach } from "vitest";

beforeEach(() => {
document.head.innerHTML = "";
Expand DownExpand Up@@ -85,6 +84,7 @@ test("unmount middle child, should show only the last title", () => {
);
expect(document.head.innerHTML).toBe(snapshot);
setVisible(false);
flush();
expect(document.head.innerHTML).toBe(snapshot);
dispose();
});
Expand DownExpand Up@@ -114,6 +114,7 @@ test("unmount last child, should show only the second last title", () => {
);
expect(document.head.innerHTML).toBe(snapshot1);
setVisible(false);
flush();
expect(document.head.innerHTML).toBe(snapshot2);
dispose();
});
Expand DownExpand Up@@ -163,8 +164,10 @@ test("mounts and unmounts title", () => {

expect(document.head.innerHTML).toBe(snapshot1);
setVisible(true);
flush();
expect(document.head.innerHTML).toBe(snapshot2);
setVisible(false);
flush();
expect(document.head.innerHTML).toBe(snapshot1);
dispose();
});
Expand All@@ -190,8 +193,10 @@ test("hydrates and unmounts title", () => {

expect(document.head.innerHTML).toBe(snapshot1);
setVisible(true);
flush();
expect(document.head.innerHTML).toBe(snapshot2);
setVisible(false);
flush();
expect(document.head.innerHTML).toBe(snapshot1);
dispose();
removeScript();
Expand DownExpand Up@@ -219,9 +224,11 @@ test("switches between titles", async () => {
() => (
<MetaProvider>
<Title>Static</Title>
<Show when={visible()} fallback={<Comp2 />}>
<Comp1 />
</Show>
<Loading fallback={null}>
<Show when={visible()} fallback={<Comp2 />}>
<Comp1 />
</Show>
</Loading>
</MetaProvider>
),
div
Expand All@@ -230,6 +237,7 @@ test("switches between titles", async () => {
await new Promise(resolve => setTimeout(resolve, 1));
expect(document.head.innerHTML).toBe(snapshot1);
setVisible(false);
flush();
await new Promise(resolve => setTimeout(resolve, 1));
expect(document.head.innerHTML).toBe(snapshot2);
dispose();
Expand DownExpand Up@@ -268,14 +276,18 @@ test("renders only the last meta with the same name", () => {
expect(document.head.innerHTML).toBe(snapshot1);
// mount first
setVisible1(true);
flush();
expect(document.head.innerHTML).toBe(snapshot2);
// mount second
setVisible2(true);
flush();
expect(document.head.innerHTML).toBe(snapshot3);
// unmount second
setVisible2(false);
flush();
// unmount first
setVisible1(false);
flush();
expect(document.head.innerHTML).toBe(snapshot1);
dispose();
});
Expand DownExpand Up@@ -322,15 +334,15 @@ test("throws error if head tag is rendered without MetaProvider", () => {
expect(() => {
let div = document.createElement("div");
render(() => <Style>{`body {}`}</Style>, div);
}).toThrowError(/<MetaProvider \/> should be in the tree/);
}).toThrowError(/Context must either be created with a default value/);
});

test("doesn't create any effect on removal", () => {
let div = document.createElement("div");

const [show, setShow] = createSignal(true);
const showAndTest = () => {
expect(getOwner()?.owner).toBeTruthy();
expect(getOwner()?._parent).toBeTruthy();
return show();
};

Expand All@@ -348,6 +360,7 @@ test("doesn't create any effect on removal", () => {
);

setShow(false);
flush();
dispose();
});

Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,7 +6,7 @@
"moduleResolution": "bundler",
"strict": true,
"jsx": "preserve",
"jsxImportSource": "solid-js"
"jsxImportSource": "@solidjs/web"
},
"include": [
"./src"
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.test.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,7 +6,7 @@
"strict": true,
"lib": ["dom", "esnext", "dom.iterable"],
"jsx": "preserve",
"jsxImportSource": "solid-js"
"jsxImportSource": "@solidjs/web"
},
"include": [
"./test"
Expand Down