diff --git a/packages/ui-next/api.ts b/packages/ui-next/api.ts index 930999c04..763157b3d 100644 --- a/packages/ui-next/api.ts +++ b/packages/ui-next/api.ts @@ -1,2 +1,4 @@ export type { Context } from './src/context'; +export { usePageData } from './src/pageData'; +export type { PageData } from './src/pageData'; export type { ComponentName } from './src/registry'; diff --git a/packages/ui-next/index.ts b/packages/ui-next/index.ts index 7611e4d5b..c2bd8226d 100644 --- a/packages/ui-next/index.ts +++ b/packages/ui-next/index.ts @@ -69,7 +69,7 @@ export async function apply(ctx: Context) { }, }); const middleware = c2k(vite.middlewares); - const capture = ['/@vite/', '/src/', '/node_modules/', '/@react-refresh', '/@fs']; + const capture = ['/@vite/', '/src/', '/node_modules/', '/@react-refresh', '/@fs', '/@id/']; for (const route of capture) { ctx.server.addCaptureRoute(route, middleware); } @@ -78,7 +78,7 @@ export async function apply(ctx: Context) { name: 'next', accept: [], output: 'html', - asFallback: false, + asFallback: true, priority: 100, async render(name, args, context) { const data = { diff --git a/packages/ui-next/src/App.tsx b/packages/ui-next/src/App.tsx index b0fcd4e9e..4b2519950 100644 --- a/packages/ui-next/src/App.tsx +++ b/packages/ui-next/src/App.tsx @@ -1,5 +1,10 @@ +import { usePageData } from './pageData'; import { Component } from './registry'; -const AppInner = Component('page:app', () =>
app
); +const AppInner = Component('page:app', () => { + const { data } = usePageData(); + + return
app, page:{data.name}
; +}); export default AppInner; diff --git a/packages/ui-next/src/main.tsx b/packages/ui-next/src/main.tsx index 7c8beca82..61912047a 100644 --- a/packages/ui-next/src/main.tsx +++ b/packages/ui-next/src/main.tsx @@ -3,14 +3,22 @@ import { createRoot } from 'react-dom/client'; import plugins from 'virtual:hydro-plugins'; import App from './App'; import { createContext } from './context'; +import { type PageData, PageDataProvider } from './pageData'; const ctx = createContext(); for (const plugin of plugins) { plugin.apply(ctx); } +const injectionEl = document.getElementById('__HYDRO_INJECTION__'); +const initialData: PageData = injectionEl + ? JSON.parse(injectionEl.textContent!) + : { name: 'invalid_init', args: {}, url: window.location.pathname }; + createRoot(document.getElementById('root')!).render( - + + + , ); diff --git a/packages/ui-next/src/pageData.tsx b/packages/ui-next/src/pageData.tsx new file mode 100644 index 000000000..498a8e3b0 --- /dev/null +++ b/packages/ui-next/src/pageData.tsx @@ -0,0 +1,31 @@ +import { createContext, type ReactNode, useContext, useState } from 'react'; + +export interface PageData { + name: string; + args: Record; + url: string; + [key: string]: any; +} + +interface PageDataContextValue { + data: PageData; + setData: (data: PageData) => void; +} + +const PageDataContext = createContext(null); + +export function PageDataProvider({ initial, children }: { initial: PageData, children: ReactNode }) { + const [data, setData] = useState(initial); + return ( + + {children} + + ); +} + +// eslint-disable-next-line react-refresh/only-export-components +export function usePageData(): PageDataContextValue { + const ctx = useContext(PageDataContext); + if (!ctx) throw new Error('usePageData must be used within PageDataProvider'); + return ctx; +}