Giter Site home page Giter Site logo

vikejs / vike-vue Goto Github PK

View Code? Open in Web Editor NEW
37.0 37.0 6.0 1.05 MB

๐Ÿ”จ Vue integration for Vike

Home Page: https://vike.dev/vike-vue

License: MIT License

TypeScript 95.83% JavaScript 4.17%
full-stack node server-rendering ssr static-site-generator vike vikejs vite vite-plugin vite-ssr vitejs vue vue-ssr web-framework

vike-vue's People

Contributors

4350pchris avatar brillout avatar dependabot[bot] avatar jonaskuske avatar lourot avatar magne4000 avatar pdanpdan avatar phonzammi avatar renovate[bot] avatar timjohns avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

vike-vue's Issues

(Re-)introduce fine-grained head settings

In addition to the title, favicon, and lang, I would find it handy to be able to specify a canonical URL in the page config.

This could be beneficial for other SSG sites optimized for search engines (see How to specify a canonical with rel="canonical" and other methods.

I currently implement this in my HeadDefault.vue as below, but it seems to closely match the pattern in the latest onRender{Client|Html} code, and may have broader appeal beyond my specific use case, so if you think it would be beneficial, please let me know and I'll submit a PR. Curious also why it appears that description was removed in the latest code, as I also configure description on page-by-page basis.

e.g.

const canonical = getHeadSetting('canonical', pageContext)

const canonicalTag = !canonical ? '' : escapeInject`<link rel="canonical" href="${canonical}" />`

Replaces my specific implementation:

<template class="h-100">
  <meta charset="UTF-8" />
  <link rel="apple-touch-icon" sizes="120x120" href="/favicons/apple-touch-icon.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/favicons/favicon-32x32.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/favicons/favicon-16x16.png">
  <link v-if="canonical" rel="canonical" :href="canonical">
  <link rel="manifest" href="/favicons/site.webmanifest">
  <link rel="shortcut icon" type="image/x-icon" href="/favicons/favicon.ico">
  <meta name="msapplication-TileColor" content="#da532c">
  <meta name="msapplication-config" content="/favicons/browserconfig.xml">
  <meta name="theme-color" content="#ffffff">
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
</template>

<script lang="ts" setup>
import { usePageContext } from 'vike-vue/usePageContext'
import { PageContext } from 'vike/types';

const pageContext = usePageContext();


function getCanonical(pageContext: PageContext): null | string {
  const canonicalConfig = pageContext.configEntries.canonical?.[0]
  if (!canonicalConfig) {
    return null
  }
  const canonical = canonicalConfig.configValue
  if (typeof canonical === 'string') {
    return canonical
  }
  const { configDefinedAt } = canonicalConfig;
  
  if (canonical instanceof Function || typeof canonical === 'function') {
    const val = canonical(pageContext)
    if (typeof val !== 'string') {
      throw new Error(configDefinedAt + ' should return a string')
    }
    return val
  }
  throw new Error(configDefinedAt + ' should be a string or a function returning a string')

}

const canonical = getCanonical(pageContext);

</script>

vikeVuePinia causes error

import vikeVue from "vike-vue/config";
import type { Config } from "vike/types";
import Head from "../layouts/HeadDefault.vue";
import Layout from "../layouts/LayoutDefault.vue";
import vikeVuePinia from 'vike-vue-pinia/config'
// Default config (can be overridden by pages)
export default {
  Layout,
  Head,
  // <title>
  title: "BackOffice",
  extends: [vikeVue, vikeVuePinia],
} satisfies Config;

error:

4:45:05 PM [vike][request(1)] Following error was thrown by the onRenderHtml() hook defined at vike-vue/renderer/onRenderHtml
TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'Object'
    |     property '_context' -> object with constructor 'Object'
    --- property 'app' closes the circle
    at JSON.stringify (<anonymous>)
    at Object.toDisplayString (/Users/james/www/admin/node_modules/.pnpm/@[email protected]/node_modules/@vue/shared/dist/shared.cjs.js:465:154)
    at Module.ssrInterpolate (/Users/james/www/admin/node_modules/.pnpm/@[email protected][email protected]/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:180:35)
    at _sfc_ssrRender (/Users/james/www/admin/pages/index/+Page.vue:1:1)
    at renderComponentSubTree (/Users/james/www/admin/node_modules/.pnpm/@[email protected][email protected]/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:693:9)
    at renderComponentVNode (/Users/james/www/admin/node_modules/.pnpm/@[email protected][email protected]/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:637:12)
    at renderVNode (/Users/james/www/admin/node_modules/.pnpm/@[email protected][email protected]/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:753:14)
    at renderVNodeChildren (/Users/james/www/admin/node_modules/.pnpm/@[email protected][email protected]/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:769:5)
    at ssrRenderSlotInner (/Users/james/www/admin/node_modules/.pnpm/@[email protected][email protected]/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:118:7)
    at Module.ssrRenderSlot (/Users/james/www/admin/node_modules/.pnpm/@[email protected][email protected]/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:93:3)
4:45:05 PM [vike][request(1)] HTTP response / 500
4:45:05 PM [[email protected]][Bug] You stumbled upon a Vike bug. Go to https://github.com/vikejs/vike/issues/new and copy-paste this error. A maintainer will fix the bug (usually under 24 hours).

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Location: .github/renovate.json5
Error type: Invalid JSON5 (parsing failed)
Message: JSON5.parse error: JSON5: invalid character '\"' at 21:7

Vue Devtools-Next errors when trying to evaluate pageContext

I'm not sure if this should be solved in vike or in devtools-next (https://github.com/vuejs/devtools-next) or in both.

When inspecting components that use usePageContext in script setup devtools will try to check some marker/well-known keys for internal purposes in prepare.js.

let n = G(()=>St(t.setupState[o])), r = e[o], s, a = typeof n == "function" || typeof (n == null ? void 0 : n.render) == "function" || typeof (n == null ? void 0 : n.__asyncLoader) == "function" || typeof n == "object" && n && ("setup"in n || "props"in n) || /^v[A-Z]/.test(o);

This will produce calls to getPageContextProxyForUser for key render at least, and that will produce an [vike][Wrong Usage] pageContext.render isn't defined on the client-side error.

It looks like normal (non-next) vue devtools works.

@brillout Maybe this should be forwarded to the vue devtools team, but I think you can decide better.

Nuxt Comparison

A comparison of features could be neat.

To give confidence to users that Vike Vue supports Nuxt features.

Also for us, so what we know where Vike Vue is lacking compared to Nuxt.

Register plugins that don't use `app.use`

Hey, I'm in the process of converting a project I'm working on to use this integration and replace my custom one.
However, one thing I don't know how to solve right now is registering client-side plugins that don't use app.use - specifically, the Sentry plugin.
Here's the code I'm currently using in my +onRenderClient.ts file (truncated):

import { init as sentryInit, BrowserTracing } from "@sentry/vue";
// ...
export async function onRenderClient(pageContext: PageContextClient) {
  if (!app) {
    // ...
    const { sentryRelease, sentryDsn } = pageContext;
    sentryInit({
      app,
      dsn: sentryDsn,
      integrations: (defaults) =>
        defaults.concat(
          new BrowserTracing({
            tracingOrigins: [/.*.example.com/, /^\//],
          })
        ),
      // Set tracesSampleRate to 1.0 to capture 100%
      // of transactions for performance monitoring.
      // We recommend adjusting this value in production
      tracesSampleRate: 0.2,
      logErrors: !import.meta.env.PROD,
      environment,
      release: sentryRelease,
    });
  // ...
  }
  // ...
}

Now, I could move this to the client init code or do it in my root component using import.meta.env.SSR - however, that would delay the plugin's registration and I'm worried some errors might not be propagated to Sentry in that case, which is why this is one of the first things I'm doing right now in the aforementioned file.

Any suggestions how I could leverage what's available right now to do this properly?

How to use vue plugin

I just read the doc and code that found there is no way to install and use the vue plugin with this adapter. Could you please tell me how to do or add a way to do that?

Improve DX of ClientOnly component

It'd be nice if we could have proper completion when using ClientOnly.
E.g.

// Component.vue
<template>
  <p>{{ msg }}</p>
</template>
<script lang="ts" setup>
  defineProps<{ msg: string }>()
</script>

// App.vue
<template>
  <ClientOnly
    :load="() => import('./Component.vue')"
    msg="Hello World"
  />
</template>

Here we don't get a hint for msg even though it's passed to Component.vue.

Client side routing with catch all page throwing error

I have a catch all route which works fine from SSR but when we navigate from one page to another on the client side, the navigation doesn't happen.

Repo to reproduce: https://github.com/mohammadsiddiqui/h3-vike
Steps to reproduce:

  • Navigate to home page
  • Click on the link Create (this will work)
  • Click on Update (this fails)

Catch all on client seems to be working for the first route occurrence but second time it fails.

This is the error i am getting

chunk-CRYGExF-.js:13 Error: You stumbled upon a vike-vue bug. Go to https://github.com/vikejs/vike-vue/issues/new and copy-paste this error. A maintainer will fix the bug (usually under 24 hours). at _l (chunk-CRYGExF-.js:17:5413) at ml (chunk-CRYGExF-.js:17:5691) at chunk-h72aJ6Vq.js:1:74 at Dn.fn (chunk-CRYGExF-.js:9:8919) at Dn.run (chunk-CRYGExF-.js:9:1446) at get value (chunk-CRYGExF-.js:9:9163) at li (chunk-CRYGExF-.js:9:1618) at get dirty (chunk-CRYGExF-.js:9:1165) at I.l.update (chunk-CRYGExF-.js:13:27958) at Ue (chunk-CRYGExF-.js:13:46)

I can't get working examples

I tested master and v0.5.3 tagged commit too. Same error:

$ cd examples/basic/
$ pnpm install
Scope: all 6 workspace projects
../..                                    | +218 ++++++++++++++++++++++
../..                                    | Progress: resolved 218, reused 201, downloaded 17, added 218, done

dependencies:
+ @types/node 20.10.5
+ @types/node-fetch 2.6.9
+ @vitejs/plugin-vue 4.6.0
+ cross-fetch 4.0.0
+ node-fetch 3.3.2
+ typescript 5.3.3
+ unplugin-vue-markdown 0.25.2
+ vike 0.4.152
+ vike-vue 0.5.3 <- ../../vike-vue
+ vite 5.0.10
+ vue 3.3.13

Done in 2.8s
$ pnpm run dev

> @ dev /MY_DIRS_HERE/vike-vue/examples/basic
> vite dev

19:28:05 [vike][config][Wrong Usage] The import path 'vike-vue' in /pages/+config.h.ts couldn't be resolved: does 'vike-vue' exist?
  VITE v5.0.10  ready in 576 ms
  โžœ  Local:   http://localhost:3000/
  โžœ  Network: use --host to expose
  โžœ  press h + enter to show help
19:28:09 [vike][request(1)] HTTP request: /
19:28:09 [vike][request(1)] Couldn't load configuration: see error above.
19:28:11 [vike][request(2)] HTTP request: /sw.js
19:28:11 [vike][request(2)] Couldn't load configuration: see error above.

And in browser I see blank page with one line: Cannot GET /

I have:

$ node --version
v18.17.1

$ pnpm --version
8.11.0

Setting the bodyHtmlBegin property breaks the page functionality

Description

import vikeVue from "vike-vue/config";
import type { Config } from "vike/types";
import Head from "../layouts/HeadDefault.vue";
import Layout from "../layouts/LayoutDefault.vue";

// Default config (can be overridden by pages)
export default {
Layout,
Head,
// <title>
//# BATI.has("auth0") || BATI.has("firebase-auth") || BATI.has("authjs")
passToClient: ["user"],
title: "My Vike App",
extends: vikeVue,
stream: "web",
bodyHtmlEnd: '

1111111
',
} satisfies Config;

After switching pages, all clicking and other functions became invalid
my-app.zip

`<meta charset="UTF-8" />` should be rendered at the start of `head`

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta#charset

It should be rendered in the first 1024 bytes of HTML, but placing stylesheets before cannot guarantee this.
And if it's not the stylesheets might load as another charset (if the server does not send the right content-type).

What is rendered by examples/full:

<!DOCTYPE html>
<html lang="en">
  <head>
    <link rel="stylesheet" type="text/css" href="/components/Link.vue?vue&type=style&index=0&scoped=409c8661&lang.css?direct">
    <link rel="stylesheet" type="text/css" href="/pages/global.css?direct">
    <link rel="stylesheet" type="text/css" href="/pages/+Layout.vue?vue&type=style&index=0&lang.css?direct">
    <link rel="stylesheet" type="text/css" href="/pages/+Layout.vue?vue&type=style&index=1&scoped=c1413baa&lang.css?direct">
    <link rel="stylesheet" type="text/css" href="/pages/images/Image.vue?vue&type=style&index=0&scoped=c8a68a87&lang.css?direct">
    <meta charset="UTF-8" />
    <title>My Vike + Vue App</title>
    <meta property="og:title" content="My Vike + Vue App">

Possible leftover properties in `pageContextReactive` after `pageChange`

In createVueApp in changePage the content of pageContext is placed in pageContextReactive using Object.assign.
That might lead to leftover properties from previous pageContext if the new one is missing those properties.
The shape changing problem from dataReactive should not creep here as pageContext is always object.

How to add some className to body?

How to add some className to body?
For example I want initially to have dark class for tailwind dark theme by default for all my pages.

Improve hooks?

  • How about deprecating onBeforeMount() in favor of onCreateApp()? AFAICT the onBeforeMount() hooks of vike-{pinia,vue-query} can be merged into onCreateApp().
  • How about deprecating onAfterRenderSSRApp() in favor of a new hook onAfterRenderHtml() that is called right before escapeInject? Users could use !!pageContext.Page to check whether the app is SSR'ing. Also, a neat thing here is that the new name would then align with vike-react's hooks.

Export Vike configuration at `/config`

  import type { Config } from 'vike/types'
  import vikeVue from 'vike-vue/config'
- import vikePinia from 'vike-pinia'
+ import vikePinia from 'vike-pinia/config'

  export default {
    extends: [vikeVue, vikePinia],
  } satisfies Config

Same for vike-vue-query.

CSS-in-JS with SSR

Unable to extract CSS and put it into tag. For example:

import { createSSRApp } from 'vue'
import { renderToString } from '@vue/server-renderer'
import { setup } = from '@css-render/vue3-ssr'

// For each request, you need to create a new app
const ssrApp = createSSRApp(App)
const { collect } = setup(ssrApp)

renderToString(ssrApp).then(appHtml => {
  const css = collect()
  const page = `<!DOCTYPE html>
  <html>
    <head>${css}</head>
    <body><div id="app">${appHtml}</div></body>
  </html>`
})

as you see here we can extract CSS and render as part of HTML template.

I didn't found a way how to do it properly. Probably a new functionality should be added

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Rate-Limited

These updates are currently rate-limited. Click on a checkbox below to force their creation now.

  • chore(deps): update dependency vike to v0.4.184
  • chore(deps): update dependency @types/node to v22.3.0
  • ๐Ÿ” Create all rate-limited PRs at once ๐Ÿ”

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/ci.yml
  • actions/checkout v4
  • pnpm/action-setup v4
  • actions/setup-node v4
.github/workflows/discord.yml
.github/workflows/formatting.yml
  • actions/checkout v4
  • pnpm/action-setup v4
npm
package.json
  • @biomejs/biome ^1.7.0
  • @brillout/test-e2e ^0.5.33
  • @brillout/test-types ^0.1.14
  • playwright ^1.44.1
  • prettier ^3.2.5
  • pnpm 9.6.0
packages/vike-vue-pinia/package.json
  • @brillout/release-me ^0.3.8
  • @types/node ^22.1.0
  • pinia ^2.1.7
  • typescript ^5.4.5
  • vike ^0.4.183
  • vike-vue ^0.8.1
  • vue ^3.4.36
  • vue-tsc ^2.0.13
  • pinia >=2.0.0
  • vike-vue >=0.7.0
  • vue >=3.0.0
packages/vike-vue-query/package.json
  • @brillout/release-me ^0.3.8
  • @tanstack/vue-query ^5.29.0
  • @types/node ^22.1.0
  • typescript ^5.4.5
  • vike ^0.4.183
  • vike-vue ^0.8.1
  • vue ^3.4.36
  • vue-tsc ^2.0.13
  • @tanstack/vue-query >=5.0.0
  • vike-vue >=0.7.0
  • vue >=3.0.0
packages/vike-vue/package.json
  • @brillout/release-me ^0.3.8
  • @types/node ^22.1.0
  • @vitejs/plugin-vue ^5.0.4
  • typescript ^5.5.4
  • vike ^0.4.183
  • vite ^5.4.0
  • vite-plugin-dts ^3.8.3
  • vue ^3.4.36
  • vue-tsc ^2.0.13
  • vike >=0.4.183
  • vue >=3.0.0

  • Check this box to trigger a request for Renovate to run again on this repository

useConfig sets _configFromHook and then getHeadHtml deletes them before being used for html/body attributes

_headAlreadySet does not work as expected on client side

_headAlreadySet has the same problem as _configFromHook.

I made a simple repro for the problem in #179

  • in useConfig (in useConfig-client) the check is against _headAlreadySet from reactive pageContext
  • in _headAlreadySet (in onRenderClient) pageContext is not created reactive with a _headAlreadySet key

What I can see is:

  • setting title on server side works as expected
  • setting title on client side on navigation works as expected
  • setting title on client side after navigation is done (eg. in a setTimeout) does not work

Rest of comments are here: #178 (comment)

Wrong data in `useData` after client side navigation

Using examples/full:

  • navigate to http://localhost:3000/star-wars/1 (page must be server loaded, without client navigation - so please reload page)
  • navigate to 'Data fetching' using link in sidebar

An error will occur.
useData will return the original object from http://localhost:3000/star-wars/1 combined with the array from http://localhost:3000/star-wars (because the base structure is an object the array content is converted to objects keys also)

I think the data should always be re-created

How to deploy to IIS server?

Thank you for making such awesome middleware. It is working well on my local setup, but I need some assistance with deploying it on an IIS server.

Could you please guide me on how to deploy this in an IIS server? Specifically, is there a way to run the ssr.js file in IIS?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.