Initial commit
This commit is contained in:
commit
78f8d225ee
21173 changed files with 2907774 additions and 0 deletions
505
node_modules/next/dist/esm/client/components/app-router.js
generated
vendored
Normal file
505
node_modules/next/dist/esm/client/components/app-router.js
generated
vendored
Normal file
|
|
@ -0,0 +1,505 @@
|
|||
'use client';
|
||||
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
||||
import React, { use, useEffect, useMemo, startTransition, useInsertionEffect, useDeferredValue } from 'react';
|
||||
import { AppRouterContext, LayoutRouterContext, GlobalLayoutRouterContext } from '../../shared/lib/app-router-context.shared-runtime';
|
||||
import { ACTION_RESTORE } from './router-reducer/router-reducer-types';
|
||||
import { createHrefFromUrl } from './router-reducer/create-href-from-url';
|
||||
import { SearchParamsContext, PathnameContext, PathParamsContext } from '../../shared/lib/hooks-client-context.shared-runtime';
|
||||
import { dispatchAppRouterAction, useActionQueue } from './use-action-queue';
|
||||
import { default as DefaultGlobalError, ErrorBoundary } from './error-boundary';
|
||||
import { isBot } from '../../shared/lib/router/utils/is-bot';
|
||||
import { addBasePath } from '../add-base-path';
|
||||
import { AppRouterAnnouncer } from './app-router-announcer';
|
||||
import { RedirectBoundary } from './redirect-boundary';
|
||||
import { findHeadInCache } from './router-reducer/reducers/find-head-in-cache';
|
||||
import { unresolvedThenable } from './unresolved-thenable';
|
||||
import { removeBasePath } from '../remove-base-path';
|
||||
import { hasBasePath } from '../has-base-path';
|
||||
import { getSelectedParams } from './router-reducer/compute-changed-path';
|
||||
import { useNavFailureHandler } from './nav-failure-handler';
|
||||
import { dispatchTraverseAction, publicAppRouterInstance } from './app-router-instance';
|
||||
import { getRedirectTypeFromError, getURLFromRedirectError } from './redirect';
|
||||
import { isRedirectError, RedirectType } from './redirect-error';
|
||||
import { pingVisibleLinks } from './links';
|
||||
const globalMutable = {};
|
||||
export function isExternalURL(url) {
|
||||
return url.origin !== window.location.origin;
|
||||
}
|
||||
/**
|
||||
* Given a link href, constructs the URL that should be prefetched. Returns null
|
||||
* in cases where prefetching should be disabled, like external URLs, or
|
||||
* during development.
|
||||
* @param href The href passed to <Link>, router.prefetch(), or similar
|
||||
* @returns A URL object to prefetch, or null if prefetching should be disabled
|
||||
*/ export function createPrefetchURL(href) {
|
||||
// Don't prefetch for bots as they don't navigate.
|
||||
if (isBot(window.navigator.userAgent)) {
|
||||
return null;
|
||||
}
|
||||
let url;
|
||||
try {
|
||||
url = new URL(addBasePath(href), window.location.href);
|
||||
} catch (_) {
|
||||
// TODO: Does this need to throw or can we just console.error instead? Does
|
||||
// anyone rely on this throwing? (Seems unlikely.)
|
||||
throw Object.defineProperty(new Error("Cannot prefetch '" + href + "' because it cannot be converted to a URL."), "__NEXT_ERROR_CODE", {
|
||||
value: "E234",
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
// Don't prefetch during development (improves compilation performance)
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
return null;
|
||||
}
|
||||
// External urls can't be prefetched in the same way.
|
||||
if (isExternalURL(url)) {
|
||||
return null;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
function HistoryUpdater(param) {
|
||||
let { appRouterState } = param;
|
||||
useInsertionEffect(()=>{
|
||||
if (process.env.__NEXT_APP_NAV_FAIL_HANDLING) {
|
||||
// clear pending URL as navigation is no longer
|
||||
// in flight
|
||||
window.next.__pendingUrl = undefined;
|
||||
}
|
||||
const { tree, pushRef, canonicalUrl } = appRouterState;
|
||||
const historyState = {
|
||||
...pushRef.preserveCustomHistoryState ? window.history.state : {},
|
||||
// Identifier is shortened intentionally.
|
||||
// __NA is used to identify if the history entry can be handled by the app-router.
|
||||
// __N is used to identify if the history entry can be handled by the old router.
|
||||
__NA: true,
|
||||
__PRIVATE_NEXTJS_INTERNALS_TREE: tree
|
||||
};
|
||||
if (pushRef.pendingPush && // Skip pushing an additional history entry if the canonicalUrl is the same as the current url.
|
||||
// This mirrors the browser behavior for normal navigation.
|
||||
createHrefFromUrl(new URL(window.location.href)) !== canonicalUrl) {
|
||||
// This intentionally mutates React state, pushRef is overwritten to ensure additional push/replace calls do not trigger an additional history entry.
|
||||
pushRef.pendingPush = false;
|
||||
window.history.pushState(historyState, '', canonicalUrl);
|
||||
} else {
|
||||
window.history.replaceState(historyState, '', canonicalUrl);
|
||||
}
|
||||
}, [
|
||||
appRouterState
|
||||
]);
|
||||
useEffect(()=>{
|
||||
// The Next-Url and the base tree may affect the result of a prefetch
|
||||
// task. Re-prefetch all visible links with the updated values. In most
|
||||
// cases, this will not result in any new network requests, only if
|
||||
// the prefetch result actually varies on one of these inputs.
|
||||
if (process.env.__NEXT_CLIENT_SEGMENT_CACHE) {
|
||||
pingVisibleLinks(appRouterState.nextUrl, appRouterState.tree);
|
||||
}
|
||||
}, [
|
||||
appRouterState.nextUrl,
|
||||
appRouterState.tree
|
||||
]);
|
||||
return null;
|
||||
}
|
||||
export function createEmptyCacheNode() {
|
||||
return {
|
||||
lazyData: null,
|
||||
rsc: null,
|
||||
prefetchRsc: null,
|
||||
head: null,
|
||||
prefetchHead: null,
|
||||
parallelRoutes: new Map(),
|
||||
loading: null,
|
||||
navigatedAt: -1
|
||||
};
|
||||
}
|
||||
function copyNextJsInternalHistoryState(data) {
|
||||
if (data == null) data = {};
|
||||
const currentState = window.history.state;
|
||||
const __NA = currentState == null ? void 0 : currentState.__NA;
|
||||
if (__NA) {
|
||||
data.__NA = __NA;
|
||||
}
|
||||
const __PRIVATE_NEXTJS_INTERNALS_TREE = currentState == null ? void 0 : currentState.__PRIVATE_NEXTJS_INTERNALS_TREE;
|
||||
if (__PRIVATE_NEXTJS_INTERNALS_TREE) {
|
||||
data.__PRIVATE_NEXTJS_INTERNALS_TREE = __PRIVATE_NEXTJS_INTERNALS_TREE;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
function Head(param) {
|
||||
let { headCacheNode } = param;
|
||||
// If this segment has a `prefetchHead`, it's the statically prefetched data.
|
||||
// We should use that on initial render instead of `head`. Then we'll switch
|
||||
// to `head` when the dynamic response streams in.
|
||||
const head = headCacheNode !== null ? headCacheNode.head : null;
|
||||
const prefetchHead = headCacheNode !== null ? headCacheNode.prefetchHead : null;
|
||||
// If no prefetch data is available, then we go straight to rendering `head`.
|
||||
const resolvedPrefetchRsc = prefetchHead !== null ? prefetchHead : head;
|
||||
// We use `useDeferredValue` to handle switching between the prefetched and
|
||||
// final values. The second argument is returned on initial render, then it
|
||||
// re-renders with the first argument.
|
||||
return useDeferredValue(head, resolvedPrefetchRsc);
|
||||
}
|
||||
/**
|
||||
* The global router that wraps the application components.
|
||||
*/ function Router(param) {
|
||||
let { actionQueue, assetPrefix, globalError } = param;
|
||||
const state = useActionQueue(actionQueue);
|
||||
const { canonicalUrl } = state;
|
||||
// Add memoized pathname/query for useSearchParams and usePathname.
|
||||
const { searchParams, pathname } = useMemo(()=>{
|
||||
const url = new URL(canonicalUrl, typeof window === 'undefined' ? 'http://n' : window.location.href);
|
||||
return {
|
||||
// This is turned into a readonly class in `useSearchParams`
|
||||
searchParams: url.searchParams,
|
||||
pathname: hasBasePath(url.pathname) ? removeBasePath(url.pathname) : url.pathname
|
||||
};
|
||||
}, [
|
||||
canonicalUrl
|
||||
]);
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
const { cache, prefetchCache, tree } = state;
|
||||
// This hook is in a conditional but that is ok because `process.env.NODE_ENV` never changes
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
useEffect(()=>{
|
||||
// Add `window.nd` for debugging purposes.
|
||||
// This is not meant for use in applications as concurrent rendering will affect the cache/tree/router.
|
||||
// @ts-ignore this is for debugging
|
||||
window.nd = {
|
||||
router: publicAppRouterInstance,
|
||||
cache,
|
||||
prefetchCache,
|
||||
tree
|
||||
};
|
||||
}, [
|
||||
cache,
|
||||
prefetchCache,
|
||||
tree
|
||||
]);
|
||||
}
|
||||
useEffect(()=>{
|
||||
// If the app is restored from bfcache, it's possible that
|
||||
// pushRef.mpaNavigation is true, which would mean that any re-render of this component
|
||||
// would trigger the mpa navigation logic again from the lines below.
|
||||
// This will restore the router to the initial state in the event that the app is restored from bfcache.
|
||||
function handlePageShow(event) {
|
||||
var _window_history_state;
|
||||
if (!event.persisted || !((_window_history_state = window.history.state) == null ? void 0 : _window_history_state.__PRIVATE_NEXTJS_INTERNALS_TREE)) {
|
||||
return;
|
||||
}
|
||||
// Clear the pendingMpaPath value so that a subsequent MPA navigation to the same URL can be triggered.
|
||||
// This is necessary because if the browser restored from bfcache, the pendingMpaPath would still be set to the value
|
||||
// of the last MPA navigation.
|
||||
globalMutable.pendingMpaPath = undefined;
|
||||
dispatchAppRouterAction({
|
||||
type: ACTION_RESTORE,
|
||||
url: new URL(window.location.href),
|
||||
tree: window.history.state.__PRIVATE_NEXTJS_INTERNALS_TREE
|
||||
});
|
||||
}
|
||||
window.addEventListener('pageshow', handlePageShow);
|
||||
return ()=>{
|
||||
window.removeEventListener('pageshow', handlePageShow);
|
||||
};
|
||||
}, []);
|
||||
useEffect(()=>{
|
||||
// Ensure that any redirect errors that bubble up outside of the RedirectBoundary
|
||||
// are caught and handled by the router.
|
||||
function handleUnhandledRedirect(event) {
|
||||
const error = 'reason' in event ? event.reason : event.error;
|
||||
if (isRedirectError(error)) {
|
||||
event.preventDefault();
|
||||
const url = getURLFromRedirectError(error);
|
||||
const redirectType = getRedirectTypeFromError(error);
|
||||
// TODO: This should access the router methods directly, rather than
|
||||
// go through the public interface.
|
||||
if (redirectType === RedirectType.push) {
|
||||
publicAppRouterInstance.push(url, {});
|
||||
} else {
|
||||
publicAppRouterInstance.replace(url, {});
|
||||
}
|
||||
}
|
||||
}
|
||||
window.addEventListener('error', handleUnhandledRedirect);
|
||||
window.addEventListener('unhandledrejection', handleUnhandledRedirect);
|
||||
return ()=>{
|
||||
window.removeEventListener('error', handleUnhandledRedirect);
|
||||
window.removeEventListener('unhandledrejection', handleUnhandledRedirect);
|
||||
};
|
||||
}, []);
|
||||
// When mpaNavigation flag is set do a hard navigation to the new url.
|
||||
// Infinitely suspend because we don't actually want to rerender any child
|
||||
// components with the new URL and any entangled state updates shouldn't
|
||||
// commit either (eg: useTransition isPending should stay true until the page
|
||||
// unloads).
|
||||
//
|
||||
// This is a side effect in render. Don't try this at home, kids. It's
|
||||
// probably safe because we know this is a singleton component and it's never
|
||||
// in <Offscreen>. At least I hope so. (It will run twice in dev strict mode,
|
||||
// but that's... fine?)
|
||||
const { pushRef } = state;
|
||||
if (pushRef.mpaNavigation) {
|
||||
// if there's a re-render, we don't want to trigger another redirect if one is already in flight to the same URL
|
||||
if (globalMutable.pendingMpaPath !== canonicalUrl) {
|
||||
const location = window.location;
|
||||
if (pushRef.pendingPush) {
|
||||
location.assign(canonicalUrl);
|
||||
} else {
|
||||
location.replace(canonicalUrl);
|
||||
}
|
||||
globalMutable.pendingMpaPath = canonicalUrl;
|
||||
}
|
||||
// TODO-APP: Should we listen to navigateerror here to catch failed
|
||||
// navigations somehow? And should we call window.stop() if a SPA navigation
|
||||
// should interrupt an MPA one?
|
||||
use(unresolvedThenable);
|
||||
}
|
||||
useEffect(()=>{
|
||||
const originalPushState = window.history.pushState.bind(window.history);
|
||||
const originalReplaceState = window.history.replaceState.bind(window.history);
|
||||
// Ensure the canonical URL in the Next.js Router is updated when the URL is changed so that `usePathname` and `useSearchParams` hold the pushed values.
|
||||
const applyUrlFromHistoryPushReplace = (url)=>{
|
||||
var _window_history_state;
|
||||
const href = window.location.href;
|
||||
const tree = (_window_history_state = window.history.state) == null ? void 0 : _window_history_state.__PRIVATE_NEXTJS_INTERNALS_TREE;
|
||||
startTransition(()=>{
|
||||
dispatchAppRouterAction({
|
||||
type: ACTION_RESTORE,
|
||||
url: new URL(url != null ? url : href, href),
|
||||
tree
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Patch pushState to ensure external changes to the history are reflected in the Next.js Router.
|
||||
* Ensures Next.js internal history state is copied to the new history entry.
|
||||
* Ensures usePathname and useSearchParams hold the newly provided url.
|
||||
*/ window.history.pushState = function pushState(data, _unused, url) {
|
||||
// Avoid a loop when Next.js internals trigger pushState/replaceState
|
||||
if ((data == null ? void 0 : data.__NA) || (data == null ? void 0 : data._N)) {
|
||||
return originalPushState(data, _unused, url);
|
||||
}
|
||||
data = copyNextJsInternalHistoryState(data);
|
||||
if (url) {
|
||||
applyUrlFromHistoryPushReplace(url);
|
||||
}
|
||||
return originalPushState(data, _unused, url);
|
||||
};
|
||||
/**
|
||||
* Patch replaceState to ensure external changes to the history are reflected in the Next.js Router.
|
||||
* Ensures Next.js internal history state is copied to the new history entry.
|
||||
* Ensures usePathname and useSearchParams hold the newly provided url.
|
||||
*/ window.history.replaceState = function replaceState(data, _unused, url) {
|
||||
// Avoid a loop when Next.js internals trigger pushState/replaceState
|
||||
if ((data == null ? void 0 : data.__NA) || (data == null ? void 0 : data._N)) {
|
||||
return originalReplaceState(data, _unused, url);
|
||||
}
|
||||
data = copyNextJsInternalHistoryState(data);
|
||||
if (url) {
|
||||
applyUrlFromHistoryPushReplace(url);
|
||||
}
|
||||
return originalReplaceState(data, _unused, url);
|
||||
};
|
||||
/**
|
||||
* Handle popstate event, this is used to handle back/forward in the browser.
|
||||
* By default dispatches ACTION_RESTORE, however if the history entry was not pushed/replaced by app-router it will reload the page.
|
||||
* That case can happen when the old router injected the history entry.
|
||||
*/ const onPopState = (event)=>{
|
||||
if (!event.state) {
|
||||
// TODO-APP: this case only happens when pushState/replaceState was called outside of Next.js. It should probably reload the page in this case.
|
||||
return;
|
||||
}
|
||||
// This case happens when the history entry was pushed by the `pages` router.
|
||||
if (!event.state.__NA) {
|
||||
window.location.reload();
|
||||
return;
|
||||
}
|
||||
// TODO-APP: Ideally the back button should not use startTransition as it should apply the updates synchronously
|
||||
// Without startTransition works if the cache is there for this path
|
||||
startTransition(()=>{
|
||||
dispatchTraverseAction(window.location.href, event.state.__PRIVATE_NEXTJS_INTERNALS_TREE);
|
||||
});
|
||||
};
|
||||
// Register popstate event to call onPopstate.
|
||||
window.addEventListener('popstate', onPopState);
|
||||
return ()=>{
|
||||
window.history.pushState = originalPushState;
|
||||
window.history.replaceState = originalReplaceState;
|
||||
window.removeEventListener('popstate', onPopState);
|
||||
};
|
||||
}, []);
|
||||
const { cache, tree, nextUrl, focusAndScrollRef } = state;
|
||||
const matchingHead = useMemo(()=>{
|
||||
return findHeadInCache(cache, tree[1]);
|
||||
}, [
|
||||
cache,
|
||||
tree
|
||||
]);
|
||||
// Add memoized pathParams for useParams.
|
||||
const pathParams = useMemo(()=>{
|
||||
return getSelectedParams(tree);
|
||||
}, [
|
||||
tree
|
||||
]);
|
||||
const layoutRouterContext = useMemo(()=>{
|
||||
return {
|
||||
parentTree: tree,
|
||||
parentCacheNode: cache,
|
||||
parentSegmentPath: null,
|
||||
// Root node always has `url`
|
||||
// Provided in AppTreeContext to ensure it can be overwritten in layout-router
|
||||
url: canonicalUrl
|
||||
};
|
||||
}, [
|
||||
tree,
|
||||
cache,
|
||||
canonicalUrl
|
||||
]);
|
||||
const globalLayoutRouterContext = useMemo(()=>{
|
||||
return {
|
||||
tree,
|
||||
focusAndScrollRef,
|
||||
nextUrl
|
||||
};
|
||||
}, [
|
||||
tree,
|
||||
focusAndScrollRef,
|
||||
nextUrl
|
||||
]);
|
||||
let head;
|
||||
if (matchingHead !== null) {
|
||||
// The head is wrapped in an extra component so we can use
|
||||
// `useDeferredValue` to swap between the prefetched and final versions of
|
||||
// the head. (This is what LayoutRouter does for segment data, too.)
|
||||
//
|
||||
// The `key` is used to remount the component whenever the head moves to
|
||||
// a different segment.
|
||||
const [headCacheNode, headKey] = matchingHead;
|
||||
head = /*#__PURE__*/ _jsx(Head, {
|
||||
headCacheNode: headCacheNode
|
||||
}, headKey);
|
||||
} else {
|
||||
head = null;
|
||||
}
|
||||
let content = /*#__PURE__*/ _jsxs(RedirectBoundary, {
|
||||
children: [
|
||||
head,
|
||||
cache.rsc,
|
||||
/*#__PURE__*/ _jsx(AppRouterAnnouncer, {
|
||||
tree: tree
|
||||
})
|
||||
]
|
||||
});
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
// In development, we apply few error boundaries and hot-reloader:
|
||||
// - DevRootHTTPAccessFallbackBoundary: avoid using navigation API like notFound() in root layout
|
||||
// - HotReloader:
|
||||
// - hot-reload the app when the code changes
|
||||
// - render dev overlay
|
||||
// - catch runtime errors and display global-error when necessary
|
||||
if (typeof window !== 'undefined') {
|
||||
const { DevRootHTTPAccessFallbackBoundary } = require('./dev-root-http-access-fallback-boundary');
|
||||
content = /*#__PURE__*/ _jsx(DevRootHTTPAccessFallbackBoundary, {
|
||||
children: content
|
||||
});
|
||||
}
|
||||
const HotReloader = require('./react-dev-overlay/app/hot-reloader-client').default;
|
||||
content = /*#__PURE__*/ _jsx(HotReloader, {
|
||||
assetPrefix: assetPrefix,
|
||||
globalError: globalError,
|
||||
children: content
|
||||
});
|
||||
} else {
|
||||
// In production, we only apply the user-customized global error boundary.
|
||||
content = /*#__PURE__*/ _jsx(ErrorBoundary, {
|
||||
errorComponent: globalError[0],
|
||||
errorStyles: globalError[1],
|
||||
children: content
|
||||
});
|
||||
}
|
||||
return /*#__PURE__*/ _jsxs(_Fragment, {
|
||||
children: [
|
||||
/*#__PURE__*/ _jsx(HistoryUpdater, {
|
||||
appRouterState: state
|
||||
}),
|
||||
/*#__PURE__*/ _jsx(RuntimeStyles, {}),
|
||||
/*#__PURE__*/ _jsx(PathParamsContext.Provider, {
|
||||
value: pathParams,
|
||||
children: /*#__PURE__*/ _jsx(PathnameContext.Provider, {
|
||||
value: pathname,
|
||||
children: /*#__PURE__*/ _jsx(SearchParamsContext.Provider, {
|
||||
value: searchParams,
|
||||
children: /*#__PURE__*/ _jsx(GlobalLayoutRouterContext.Provider, {
|
||||
value: globalLayoutRouterContext,
|
||||
children: /*#__PURE__*/ _jsx(AppRouterContext.Provider, {
|
||||
value: publicAppRouterInstance,
|
||||
children: /*#__PURE__*/ _jsx(LayoutRouterContext.Provider, {
|
||||
value: layoutRouterContext,
|
||||
children: content
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
]
|
||||
});
|
||||
}
|
||||
export default function AppRouter(param) {
|
||||
let { actionQueue, globalErrorComponentAndStyles: [globalErrorComponent, globalErrorStyles], assetPrefix } = param;
|
||||
useNavFailureHandler();
|
||||
return /*#__PURE__*/ _jsx(ErrorBoundary, {
|
||||
// At the very top level, use the default GlobalError component as the final fallback.
|
||||
// When the app router itself fails, which means the framework itself fails, we show the default error.
|
||||
errorComponent: DefaultGlobalError,
|
||||
children: /*#__PURE__*/ _jsx(Router, {
|
||||
actionQueue: actionQueue,
|
||||
assetPrefix: assetPrefix,
|
||||
globalError: [
|
||||
globalErrorComponent,
|
||||
globalErrorStyles
|
||||
]
|
||||
})
|
||||
});
|
||||
}
|
||||
const runtimeStyles = new Set();
|
||||
let runtimeStyleChanged = new Set();
|
||||
globalThis._N_E_STYLE_LOAD = function(href) {
|
||||
let len = runtimeStyles.size;
|
||||
runtimeStyles.add(href);
|
||||
if (runtimeStyles.size !== len) {
|
||||
runtimeStyleChanged.forEach((cb)=>cb());
|
||||
}
|
||||
// TODO figure out how to get a promise here
|
||||
// But maybe it's not necessary as react would block rendering until it's loaded
|
||||
return Promise.resolve();
|
||||
};
|
||||
function RuntimeStyles() {
|
||||
const [, forceUpdate] = React.useState(0);
|
||||
const renderedStylesSize = runtimeStyles.size;
|
||||
useEffect(()=>{
|
||||
const changed = ()=>forceUpdate((c)=>c + 1);
|
||||
runtimeStyleChanged.add(changed);
|
||||
if (renderedStylesSize !== runtimeStyles.size) {
|
||||
changed();
|
||||
}
|
||||
return ()=>{
|
||||
runtimeStyleChanged.delete(changed);
|
||||
};
|
||||
}, [
|
||||
renderedStylesSize,
|
||||
forceUpdate
|
||||
]);
|
||||
const dplId = process.env.NEXT_DEPLOYMENT_ID ? "?dpl=" + process.env.NEXT_DEPLOYMENT_ID : '';
|
||||
return [
|
||||
...runtimeStyles
|
||||
].map((href, i)=>/*#__PURE__*/ _jsx("link", {
|
||||
rel: "stylesheet",
|
||||
href: "" + href + dplId,
|
||||
// @ts-ignore
|
||||
precedence: "next"
|
||||
}, i));
|
||||
}
|
||||
|
||||
//# sourceMappingURL=app-router.js.map
|
||||
Loading…
Add table
Add a link
Reference in a new issue