Salutations!
I am working on a Tailwind-css-Next.js-Typescript project trying to implement a theme toggler. It works fine except for the on-load flicker.
In the past I implemented a solution similar to https://github.com/vercel/next.js/discussions/12533 but now that only next/script is accepted, when using Typescript you can't export a script without export which paradoxically returns an Uncaught SyntaxError: Unexpected token 'export' error.Also scripts like this won't execute anyway if you add them in the Head instead of inside the body. Which in turn is a problem because tailwind wants the script in the head.
This is my current script (note that I must use export{} and create a module otherwise the Typescript linter doesn't let me save the file):
var theme = localStorage.getItem("dark-theme") || "light";
if (theme === "dark") {
document.documentElement.classList.add("dark");
}
export {};
And I try to use it like so:
import "./globals.css";
import Script from "next/script";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
{/*
<head /> will contain the components returned by the nearest parent
head.tsx. Find out more at https://beta.nextjs.org/docs/api-reference/file-conventions/head
*/}
<head />
<body>
<Script
type="module"
strategy="beforeInteractive"
src="themeScript.tsx"
/>
{children}
</body>
</html>
);
}
But this causes a Uncaught SyntaxError: Unexpected token 'export' (at themeScript.tsx:1:1)
I have also tried adding the following both in the Head and in the body. It doesn't return an error but doesn't produce a result.
<Script id="find-dark-mode">{localStorage.getItem("dark-theme") === true ? document.documentElement.classList.add('dark') : document.documentElement.classList.remove('dark')}</Script>
This question is similar to Next 13 & Tailwind Darkmode Flickering but I am asking about next 13 scripts in general.
I appreciate your time in advance.
Related
<template>
<div>
<Navbar />
<PageTitle/>
<ijsreat />
<Footer />
</div>
</template>
<script>
import Navbar from "../Layout/Navbar.vue"
import PageTitle from "../Common/PageTitle.vue"
import ijsreat from '../Journals/IJSREAT.vue'
import Footer from "../Layout/Footer.vue"
export default {
components: {
Navbar,
PageTitle,
ijsreat,
Footer,
}
}
</script>
I'm getting this error but I'm able to see the output successfully without any issue. This was showing in this particular file only. Don't know what's the issue is. I tried but all failed. Help me to solve this. My output was showing clearly but this was quite annoying in the file.
This error is new to me its quite harder to fix from my side.
Error: Operator '<' cannot be applied to types 'boolean' and 'RegExp'.
and
Error: Operator '<' cannot be applied to types 'boolean' and 'number'.'
The main problem is under the after tag. You can ignore the other parts above.
origin
I want to insert a chart (linechart) into my vuepress page.
first
I chose echart, use <script src="echarts.js"></script> to include it in my .md file, But failed.
[vite] Internal server error: Tags with side effect (<script> and <style>) are ignored in client component templates.
It seems that I can't use <script> in it? But I looked up Markdown and Vue SFC , It just says that you should avoid using more than one <script> in VuePress markdown. Does it mean I can use just a single <script> in .md file?
after
I tried to use echart vue component. Followed the tutorial, I just use register-components plugin to register it. These are my config:
.vuepress/config.ts
const { registerComponentsPlugin } = require('#vuepress/plugin-register-components')
const { path } = require('#vuepress/utils')
export default defineUserConfig({
...
plugins: [
...
registerComponentsPlugin({
componentsDir: path.resolve(__dirname, './components')
}),
]
})
.vuepress/components/TestMe.vue
<template>
<h1>Test my component</h1>
</template>
<script>
export default {
}
</script>
<style>
</style>
Isn't it a simplest component for test?
Then I add <TestMe /> to my .md file. But it failed again. The h1 title couldn't show and my web gave out a warning:
to see the warning information
I have no idea about that.
When I run npm run build and npm start on my local machine it deploys perfectly to localhost but when I try to deploy the very same code to Vercel I get the following error:
08:28:16 Failed to compile.
08:28:16 ./pages/index.tsx:5:20
08:28:16 Type error: Cannot find module '../components/layout' or its corresponding type declarations.
It definitely seems like an issue with the Layout component, I switched around the order of the important and it always fails when trying to load the Layout component. Here's the code for the component:
import Alert from "./alert";
import Footer from "./footer";
import Meta from "./meta";
type Props = {
preview?: boolean;
children: React.ReactNode;
};
const Layout = ({ preview, children }: Props) => {
return (
<>
<Meta />
<div className="min-h-screen">
<Alert preview={preview} />
<main>{children}</main>
</div>
<Footer />
</>
);
};
export default Layout;
index.tsx line 5 looks like this import Layout from "../components/layout"; and I've confirmed that that is the correct path for the Layout component.
are you sure the file name is layout.tsx not Layout.tsx :-)
I went through the same thing.
Fix layout.tsx to Layout.tsx
The file name and component name must be the same.
<template>
<div class="container">
<head>
<link rel="stylesheet" href="~assets/css/style-light.css" />
<link rel="stylesheet" href="~assets/css/login-light.css" />
</head>
</div>
</template>
Importing css like above results in this error
vue.runtime.esm.js:5717 GET http://localhost:3000/~assets/css/login-light.css net::ERR_ABORTED 404 (Not Found)
Is there really no other way loading css other than putting the whole css in the template?
The first thing you need to know is, you can't declare a html head inside any place, neither in yours tamplate, neither in yours components, neither in yours pages, neither in nowhere.
Keep in mind that you can't use a html tags for this, you will use a json schema.
take a look https://nuxtjs.org/guide/configuration for more detailed explanations.
Now about you doubt if you want to import the CSS as globally, the correct place is inside your nuxt.config.js, inside this file, you have a property called head, and inside the head we will configure all the imports.
So, inside nuxt.config.js find your head session, and then create new property called css, some thing like this:
head: {
css: [
'~/assets/style/app.styl',
'~/assets/style/main.css'
],
}
...
Another way, is import your css directly inside your component, for this you can do some thing like this:
<style scoped>
#import '~/assets/style/main.css';
</style>
OR
<style scoped src="#/assets/styles/mystyles.css">
</style>
In Nuxt, you will need a CSS loader instaled in your application too, so have sure you had intalled a "stylus" and "stylus-loader" in your app.
try to impot your css files in script like this :
<script>
import "#/assets/css/style-light.css";
import "#/assets/css/login-light.css";
///
</script>
EDIT: changed ~ to #
You could bring your files in using the head method like so :
head () {
return {
link: [
{ rel: 'stylesheet', href: '/style-light.css' },
{ rel: 'stylesheet', href: '/login-light.css' }
]
}
}
You should also move these css files into the static folder. See this discussion on the Vue forum https://forum.vuejs.org/t/nuxt-import-css-file-and-js-file/42498
I'm working on a Chrome extension that injects some UI react components into a page.
The UI components come from react-mdl. Using them requires me to include a css file in the top of my project.
Unfortunately, once the css is injected into the page, the entire page's font is changed.
Is there a way to limit the scope of the css used by react-mdl such that it doesn't affect the page into which I'm injecting?
Just posting this for posterity as accepted answer deserves credit, but if anyone finds themselves in a similar predicament, here is a snippet of the code that worked for me:
// my injected code
window.addEventListener('load', () => {
const injectDiv = document.createElement('div')
const shadowRoot = injectDiv.attachShadow({ mode: 'open' })
// note inline use of webpack raw-loader, so that the css
// file gets inserted as raw text, instead of attached to <head>
// as with the webpack style-loader
shadowRoot.innerHTML = // just using template string
`
<style>${require('raw-loader!app/styles/extension-material.css')}</style>
<div id='shadowReactRoot' />
`
document.body.appendChild(injectDiv)
ReactDOM.render(
<App />,
// note you have to start your query in the shadow DOM
// in order to find your root
shadowRoot.querySelector('#shadowReactRoot')
)
})
Then, sure enough:
I think you should use the Shadow DOM API. It is good practice for those cases when you just need to append your UI component to a webpage.
https://developers.google.com/web/fundamentals/getting-started/primers/shadowdom
As mentioned in this other SO post, <link> tag is also supported, so one can simply do as follows:
const injectedDiv = document.createElement('div');
const shadowRoot = injectedDiv.attachShadow({ mode: 'open' });
shadowRoot.innerHTML = `\
<link rel="stylesheet" type="text/css" href="${chrome.extension.getURL("bootstrap.min.css")}"></link>\
<link rel="stylesheet" type="text/css" href="${chrome.extension.getURL("whatever.css")}"></link>\
`;
document.body.appendChild(injectedDiv);
Notes:
Using chrome.extension.getURL is required for getting an extension's local resource url, see e.g. in this answer.
The linked .css resources must be declared under the web_accessible_resources property in your manifest.json (otherwise, you'll get this error)