diff --git a/packages/vue-script-setup-converter/src/lib/converter/index.ts b/packages/vue-script-setup-converter/src/lib/converter/index.ts
index 5863e10..6af55d1 100644
--- a/packages/vue-script-setup-converter/src/lib/converter/index.ts
+++ b/packages/vue-script-setup-converter/src/lib/converter/index.ts
@@ -1,3 +1,4 @@
export * from "./emitsConverter";
+export * from "./pageMetaConverter";
export * from "./propsConverter";
export * from "./setupConverter";
diff --git a/packages/vue-script-setup-converter/src/lib/converter/pageMetaConverter.test.ts b/packages/vue-script-setup-converter/src/lib/converter/pageMetaConverter.test.ts
new file mode 100644
index 0000000..9cac85b
--- /dev/null
+++ b/packages/vue-script-setup-converter/src/lib/converter/pageMetaConverter.test.ts
@@ -0,0 +1,85 @@
+import { expect, describe, it } from "vitest";
+import { CallExpression, ScriptTarget, SyntaxKind, Project } from "ts-morph";
+import { parse } from "@vue/compiler-sfc";
+import prettier from "prettier";
+import parserTypeScript from "prettier/parser-typescript";
+import { getNodeByKind } from "../helper";
+import { convertPageMeta } from "./pageMetaConverter";
+
+const parseScript = (input: string, lang: "js" | "ts" = "js") => {
+ const {
+ descriptor: { script },
+ } = parse(input);
+
+ const project = new Project({
+ tsConfigFilePath: "tsconfig.json",
+ compilerOptions: {
+ target: ScriptTarget.Latest,
+ },
+ });
+
+ const sourceFile = project.createSourceFile("s.tsx", script?.content ?? "");
+
+ const callExpression = getNodeByKind(sourceFile, SyntaxKind.CallExpression);
+
+ const pageMeta = convertPageMeta(callExpression as CallExpression, lang);
+
+ const formatedText = prettier.format(pageMeta, {
+ parser: "typescript",
+ plugins: [parserTypeScript],
+ });
+
+ return formatedText;
+};
+
+describe("convertPageMeta", () => {
+ describe("basic", () => {
+ const source = ``;
+
+ it("returns text including definePageMeta", () => {
+ const output = parseScript(source);
+
+ const expected = `definePageMeta({
+ name: "HelloWorld",
+ layout: "test-layout",
+ middleware: "test-middleware",
+});
+`;
+
+ expect(output).toBe(expected);
+ });
+ });
+
+ describe("when middleware is array", () => {
+ const source = ``;
+
+ it("returns text including definePageMeta", () => {
+ const output = parseScript(source);
+
+ const expected = `definePageMeta({
+ name: "HelloWorld",
+ layout: "test-layout",
+ middleware: ["test-middleware-1", "test-middleware-2"],
+});
+`;
+
+ expect(output).toBe(expected);
+ });
+ });
+});
diff --git a/packages/vue-script-setup-converter/src/lib/converter/pageMetaConverter.ts b/packages/vue-script-setup-converter/src/lib/converter/pageMetaConverter.ts
new file mode 100644
index 0000000..70cbf5f
--- /dev/null
+++ b/packages/vue-script-setup-converter/src/lib/converter/pageMetaConverter.ts
@@ -0,0 +1,32 @@
+import { CallExpression, PropertyAssignment } from "ts-morph";
+import { getOptionsNode } from "../helper";
+
+export const convertPageMeta = (node: CallExpression, lang: string = "js") => {
+ const nameNode = getOptionsNode(node, "name");
+ const layoutNode = getOptionsNode(node, "layout");
+ const middlewareNode = getOptionsNode(node, "middleware");
+
+ if (!nameNode && !layoutNode && !middlewareNode) return "";
+
+ return convertToDefinePageMeta({ nameNode, layoutNode, middlewareNode });
+};
+
+const convertToDefinePageMeta = ({
+ nameNode,
+ layoutNode,
+ middlewareNode,
+}: {
+ nameNode: PropertyAssignment | undefined;
+ layoutNode: PropertyAssignment | undefined;
+ middlewareNode: PropertyAssignment | undefined;
+}) => {
+ const nameProperty = nameNode ? nameNode.getText() : "";
+ const layoutProperty = layoutNode ? layoutNode.getText() : "";
+ const middlewareProperty = middlewareNode ? middlewareNode.getText() : "";
+
+ return `definePageMeta({
+ ${[nameProperty, layoutProperty, middlewareProperty]
+ .filter(Boolean)
+ .join(",")}
+ });`;
+};
diff --git a/packages/vue-script-setup-converter/src/lib/helper.ts b/packages/vue-script-setup-converter/src/lib/helper.ts
index a20b97a..c6057b7 100644
--- a/packages/vue-script-setup-converter/src/lib/helper.ts
+++ b/packages/vue-script-setup-converter/src/lib/helper.ts
@@ -17,7 +17,7 @@ export const getNodeByKind = (
export const getOptionsNode = (
node: CallExpression,
- type: "props" | "emits"
+ type: "name" | "layout" | "middleware" | "props" | "emits"
) => {
const expression = getNodeByKind(node, SyntaxKind.ObjectLiteralExpression);