Kirby 3 as Headless CMS for Vue/Nuxt

Please note that KirbyText is just an extension of Markdown, which is an extension of HTML. Which means: KirbyText may as well contain HTML. Therefore you need to strip all HTML tags from the KirbyText on the client side or you might as well parse KirbyText on the backend. However stripping HTML may not mitigate all attacks (like XSS in a link tag).

My recommendation is to only load resources from trusted sources anyway, then you won‘t need all that complex and potentially still not 100 % secure client logic.

I do get your point, but really, there is some ingrown historic (and probably irrational) fear of sending HTML over any api.

I’d rather limit my users to use kirbytext only and I work to extend as required.

I keep getting a CORS error

Access to XML:HttpRequest at 'http://localhost:888/api/pages/test' 
from origin 'http://localhost:8080' has been blocked by CORS policy: 
Response to preflight request doesn't pass access control check: 
No 'Access-Control-Allow-Origin' header is present on the 
requested resource.

If I connect with Postman, it works fine, though.

Does anyone have the same issue? Or any idea on how to fix that?

And before that I even get a 404 on the api page… Even though it is definitely there…

I’m a big fan of the new API feature but with Kirby 2 I built I own api routes through the templates and that worked much easier somehow.

Thanks a lot!

You can use the nuxt proxy module to get around this.

As an example for your case, you might configure the proxy from /kirby to http://localhost:888/api/. That way your server will pass the apis to the kirby backend transparently and you won’t have cors issues.

Let me know if you need some more details.

Regarding parsing of Kirbytext, I think the following OPTION would be amazing to have:

const requestConfig = {
  auth: {
  username: XXX,
  password: XXX,
},
  params: { select: 'files, content', parse: 'fieldA', 'fieldC', 'introtext', 'whateveryouwant' },
}

You’d basically be able to tell Kirby which fields to parse before answering the API call.
No idea how complicated it would be though.

Hey, I just discovered the amazing REST API Kirby 3 comes with and in the last few days I’ve been trying to create a simple, straightforward, zero-setup port of the Starterkit to Vue.js.

If you’re looking for something similar or want to give it a try, its here: https://github.com/jmedveckyh/kirby-vue-starterkit

5 Likes

I was really confused that even a user with a custom role/permission couldn’t access the API if panel access was set to false.

However, for some reason this role blueprint works with API access but no acess to panel (seems to force the user into an endless redirect?)

title: API
permissions:
  access:
    panel: true
    site: false
    settings: false
    pages: false
    files: false
    user: false
    users: false

imho the panel access is required since the API was designed to work very closely with the panel. almost all returned data is structured for what the panel needs.

if you are looking for a simple but secure way to query the api consider using @rbnschlz plugin: https://github.com/robinscholz/better-rest
i comes with a user blueprint just like you posted built right in.

@bnomei

i keep getting authorization problems with the better-rest plugin.

i created a new api user and set the user blueprint coming with the plugin. i set the 'basicAuth' => true in the config.php file.

i’m running locally with valet and enabled https for the website. i also tried to set 'allowInsecure' => true in the config.php to overcome the possible https-not-working problem.

still no luck when visiting <local.dev>/rest/site. am i missing something?

the plugin is intended to be called with basic auth. you can do that in js, php or the terminal



1 Like

gotcha, thanks!

out of curiosity: how does better-rest deal with authentication? does it use csrf or the api user’s email and password?

the basic auth credentials are: user email and password.

Hi Sonja,
I was wondering, how is that Cookbook recipe for using Kirby as headless CMS (with Nuxt) coming along? :blush:

I’m new to Nuxt and new-ish to Kirby, and I’m trying to get a feel if they are a good fit together for my next project.
No pressure tough!
Thanks!

@itWilllBeOK I’m new to Vue and not at all familiar with Nuxt, so I’m definitely not going to write anything about that myself in the near future.

I’d look into the examples @rbnschlz posted above.

Hello! Since some people starred the last project I made I guess they found it useful, therefore I made some additional improvements in it. And I even made a fork from it which uses a slightly different approach but makes more sense, requires 0 configuration and is more elegant.

It uses Kirby 3 as headless CMS, Vue.js for frontend, same as before, but instead of fetching the data with the REST API I just turned all the templates to .json representations and consume them from the vue frontend.

If anyone’s interested in this template it’s right here: https://github.com/jmheretik/kirby-json-vue-starterkit. Enjoy :slight_smile:

5 Likes

@jmedveckyh Thanks a lot for sharing your solution :slightly_smiling_face:.

Could you please add a license note regarding Kirby to your Readme? Otherwise people who come across your repo might think that Kirby is free software.

You’re right, I totally forgot to mention that. Updated :slight_smile:

1 Like

Just noticed the link to your repo is dead, you probably want to update it, without -json:

1 Like

Just add these to your controller :

kirby()->response()->header('Access-Control-Allow-Origin','*');
kirby()->response()->header('Access-Control-Allow-Credentials', 'true');
kirby()->response()->header('Access-Control-Allow-Methods', 'GET,HEAD,OPTIONS,POST,PUT');
kirby()->response()->header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
kirby()->response()->header('Content-type', 'application/json; charset=utf-8');

It will also work on cached pages.

Hi,
Sorry for reviving this old thread.
Have you published a Cookbook recipe for this? I’m not able to find it.
Thanks.

1 Like