Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Render XML pages Server Side using Vue templates #5918

Open
Timkor opened this issue Jun 12, 2019 — with CMTY · 5 comments

Comments

Copy link

commented Jun 12, 2019 — with CMTY

What problem does this feature solve?

Would be nice to render XML sitemaps, RSS feeds, Google Shopping feeds and similar stuff using Nuxt.js.

Why do I think this a good feature?

Because at runtime we have access to Nuxt plugins such as translation, routing and API clients (data and functionality). These plugins are often tightly coupled.

When writing stuff like this in a Nuxt module we often need to replicate functionality which is already available in the Nuxt context. Additionally, it's really easy and logically to render XML using Vue templates and more in line with the rest of the application.

What does the proposed changes look like?

Easiest solution in my eyes are adding a flag property to a page component saying it should be serverSideOnly. If this flag is set to true, it should be able to tell Nuxt that there shouldn't be rendered any layout: layout: null.

I think there should be some minor additional changes to the webpack integration for the HTML template. Which obviously, shouldn't be included in the response.

Last but not least: serverSideOnly page components should not be in the client bundle. (Including the routes).

Simple example

File: ~/pages/xml-feeds/sitemap.xml.vue:

<template>
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
        <url>
            <loc>{{generateURL('index')}}</loc>
            <changefreq>weekly</changefreq>
            <priority>1.0</priority>
        </url>
    </urlset>
</template>
<script>

export default {
    layout: null,
    serverSideOnly: true,

    methods: {
        generateURL(routeName) {
            return 'https://example.com' + this.$router.resolve(routeName).href;
        }
    }
}
</script>
This feature request is available on Nuxt community (#c9347)
@cmty cmty bot added the cmty:feature-request label Jun 12, 2019
@DenzoNL

This comment has been minimized.

Copy link

commented Jun 12, 2019

I agree, this would be very useful to have! +1

@Timkor Timkor changed the title Render XML files Server Side using Vue templates Render XML pages Server Side using Vue templates Jun 12, 2019
@dennisreimann

This comment has been minimized.

Copy link

commented Jun 12, 2019

I came here looking for the answer to a similar question: (Feel free to remove this comment in case it does not match the intention of the original issue)

Is there a way to render a page without a template? My use case would be to provide HTML fragments which could be included elsewhere (i.e. as part of a micro-frontend style application). In Nuxt-terms I need a page to be rendered without "the frame", consisting of layout and template (basically: skip rendering them as a wrapper).

@Timkor

This comment has been minimized.

Copy link
Author

commented Jun 13, 2019

@dennisreimann
Seems like a good use case for this feature.

Also I had something related in mind:
I want to render mjml templates in Vue using Nuxt.js.

This way I can leverage Nuxt.js plugins and Vue to render the template and feed that to mjml. Also easy to do using this feature!

Looks cool, the micro-frontend concept by the way!

@dennisreimann

This comment has been minimized.

Copy link

commented Jun 13, 2019

From a users perspective I can imagine this as the option to specify the template for a page, just like the layout. It'd be nice if both options could also be explicitely set to null, skipping the wrapping of the page.

In my case I'd rather go with an additional template, because I need the ability to include the {{ HEAD }} part (as it contains the assets needed in the fragment. Rright now I found only the "hook" to change the app.html file for every page, but not the option to specify an individual template like fragment.html for some pages.

@Timkor

This comment has been minimized.

Copy link
Author

commented Jun 13, 2019

Yes indeed, I agree.

However, template is already a component property (specifying the template literal). Maybe also a bit ambigious.

What would be nice is also to be able to specify how the output is wrapped. Like:

export default {
  serverSideOnly: true,
  template: null,
  
  wrapper: null
}

Specifying that the output is not wrapped at all.

Wrapper could be defaulted to the Nuxt wrapper, and overridden using a custom function:

import mjml2html from 'mjml'

export default {
  serverSideOnly: true,
  template: null,
  
  wrapper: (outputString) => {
     return mjml2html(outputString);
  }
}

https://github.com/mjmlio/mjml

I can think of endless possibilities this way!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.