;
16 | export type ArticleListDetail = Article & MicroCMSListContent;
17 |
--------------------------------------------------------------------------------
/microcms-next-jamstack-blog/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env.local
29 | .env.development.local
30 | .env.test.local
31 | .env.production.local
32 |
33 | # vercel
34 | .vercel
35 |
--------------------------------------------------------------------------------
/microcms-next-jamstack-blog/README.md:
--------------------------------------------------------------------------------
1 | # Next.js + microCMS を使ったブログのサンプル
2 |
3 | このリポジトリはJamstack ワークショップで行った Next.js + microCMS の Jamstack ブログです。
4 |
5 | 参考記事: https://microcms.io/blog/microcms-next-jamstack-blog
6 |
--------------------------------------------------------------------------------
/microcms-next-jamstack-blog/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "microcms-next-jamstack-blog",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start"
9 | },
10 | "dependencies": {
11 | "next": "9.5.4",
12 | "react": "16.13.1",
13 | "react-dom": "16.13.1",
14 | "sass": "^1.27.0"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/microcms-next-jamstack-blog/pages/404.js:
--------------------------------------------------------------------------------
1 | export default function Custom404() {
2 | return (
3 |
4 | ページがありません。
5 |
6 | );
7 | }
8 |
--------------------------------------------------------------------------------
/microcms-next-jamstack-blog/pages/_app.js:
--------------------------------------------------------------------------------
1 | import '../styles/globals.css'
2 |
3 | function MyApp({ Component, pageProps }) {
4 | return
5 | }
6 |
7 | export default MyApp
8 |
--------------------------------------------------------------------------------
/microcms-next-jamstack-blog/pages/api/hello.js:
--------------------------------------------------------------------------------
1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2 |
3 | export default (req, res) => {
4 | res.statusCode = 200
5 | res.json({ name: 'John Doe' })
6 | }
7 |
--------------------------------------------------------------------------------
/microcms-next-jamstack-blog/pages/blog/[id].js:
--------------------------------------------------------------------------------
1 | import styles from '../../styles/Home.module.scss'
2 |
3 | export default function BlogId({blog}) {
4 | return (
5 |
6 | {blog.title}
7 | {blog.publishedAt}
8 | {blog.category && `${blog.category.name}`}
9 |
15 |
16 | );
17 | }
18 |
19 | export const getStaticPaths = async () => {
20 | const key = {
21 | headers: {'X-API-KEY': process.env.API_KEY},
22 | };
23 |
24 | const res = await fetch('https://your-service.microcms.io/api/v1/blog', key);
25 | const repos = await res.json();
26 |
27 | const paths = repos.contents.map(repo => `/blog/${repo.id}`);
28 | return {paths, fallback: false};
29 | };
30 |
31 | export const getStaticProps = async context => {
32 | const id = context.params.id;
33 |
34 | const key = {
35 | headers: {'X-API-KEY': process.env.API_KEY},
36 | };
37 |
38 | const res = await fetch(
39 | 'https://your-service.microcms.io/api/v1/blog/' + id,
40 | key,
41 | );
42 |
43 | const data = await res.json();
44 |
45 | return {
46 | props: {
47 | blog: data,
48 | },
49 | };
50 | };
51 |
--------------------------------------------------------------------------------
/microcms-next-jamstack-blog/pages/index.js:
--------------------------------------------------------------------------------
1 | import Link from 'next/link';
2 |
3 | export default function Home({blog}) {
4 | return (
5 |
6 | {blog.map(blog => (
7 |
14 | ))}
15 |
16 | );
17 | }
18 |
19 |
20 | export const getStaticProps = async () => {
21 | const key = {
22 | headers: {'X-API-KEY': process.env.API_KEY},
23 | };
24 |
25 | const res = await fetch('https://your-service.microcms.io/api/v1/blog', key);
26 |
27 | const data = await res.json();
28 |
29 | return {
30 | props: {
31 | blog: data.contents,
32 | },
33 | };
34 | };
35 |
--------------------------------------------------------------------------------
/microcms-next-jamstack-blog/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microcmsio/microcms-sample/0570b1dce7cdbaf0da050a4e25fc194e929f052c/microcms-next-jamstack-blog/public/favicon.ico
--------------------------------------------------------------------------------
/microcms-next-jamstack-blog/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/microcms-next-jamstack-blog/styles/Home.module.scss:
--------------------------------------------------------------------------------
1 | .main {
2 | width: 960px;
3 | margin: 0 auto;
4 | }
5 |
6 | .title {
7 | margin-bottom: 20px;
8 | }
9 |
10 | .publishedAt {
11 | margin-bottom: 40px;
12 | }
13 |
14 | .post {
15 | & > h1 {
16 | font-size: 30px;
17 | font-weight: bold;
18 | margin: 40px 0 20px;
19 | background-color: #eee;
20 | padding: 10px 20px;
21 | border-radius: 5px;
22 | }
23 |
24 | & > h2 {
25 | font-size: 24px;
26 | font-weight: bold;
27 | margin: 40px 0 16px;
28 | border-bottom: 1px solid #ddd;
29 | }
30 |
31 | & > p {
32 | line-height: 1.8;
33 | letter-spacing: 0.2px;
34 | }
35 |
36 | & > ol {
37 | list-style-type: decimal;
38 | list-style-position: inside;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/microcms-next-jamstack-blog/styles/globals.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | padding: 0;
4 | margin: 0;
5 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
6 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
7 | }
8 |
9 | a {
10 | color: inherit;
11 | text-decoration: none;
12 | }
13 |
14 | * {
15 | box-sizing: border-box;
16 | }
17 |
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | /node_modules/
3 | /src/node_modules/@sapper/
4 | yarn-error.log
5 | /__sapper__/
6 | .env
7 |
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {"recommendations": ["svelte.svelte-vscode"]}
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/README.md:
--------------------------------------------------------------------------------
1 | # microCMS + Svelte + Sapper + TypeScript を使ったブログのサンプル
2 |
3 | 詳しくはこちらの[チュートリアル記事](https://microcms.io/blog/microcms-svelte-sapper-jamstack-blog)を参考にしてください。
4 |
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "TODO",
3 | "description": "TODO",
4 | "version": "0.0.1",
5 | "scripts": {
6 | "dev": "sapper dev",
7 | "build": "sapper build --legacy",
8 | "export": "sapper export --legacy",
9 | "start": "node __sapper__/build",
10 | "validate": "svelte-check --ignore src/node_modules/@sapper"
11 | },
12 | "dependencies": {
13 | "compression": "^1.7.1",
14 | "isomorphic-unfetch": "^3.1.0",
15 | "polka": "next",
16 | "sirv": "^1.0.0"
17 | },
18 | "devDependencies": {
19 | "@babel/core": "^7.0.0",
20 | "@babel/plugin-syntax-dynamic-import": "^7.0.0",
21 | "@babel/plugin-transform-runtime": "^7.0.0",
22 | "@babel/preset-env": "^7.0.0",
23 | "@babel/runtime": "^7.0.0",
24 | "@rollup/plugin-babel": "^5.0.0",
25 | "@rollup/plugin-commonjs": "^14.0.0",
26 | "@rollup/plugin-node-resolve": "^8.0.0",
27 | "@rollup/plugin-replace": "^2.2.0",
28 | "@rollup/plugin-typescript": "^6.0.0",
29 | "@rollup/plugin-url": "^5.0.0",
30 | "@tsconfig/svelte": "^1.0.10",
31 | "@types/compression": "^1.7.0",
32 | "@types/node": "^14.11.1",
33 | "@types/polka": "^0.5.1",
34 | "autoprefixer": "^10.2.1",
35 | "dotenv": "^8.2.0",
36 | "node-sass": "^5.0.0",
37 | "postcss": "^8.2.4",
38 | "rollup": "^2.3.4",
39 | "rollup-plugin-svelte": "^7.0.0",
40 | "rollup-plugin-terser": "^7.0.0",
41 | "sapper": "^0.28.0",
42 | "svelte": "^3.17.3",
43 | "svelte-check": "^1.0.46",
44 | "svelte-preprocess": "^4.6.1",
45 | "tslib": "^2.0.1",
46 | "typescript": "^4.0.3"
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/rollup.config.js:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import dotenv from 'dotenv';
3 | import resolve from '@rollup/plugin-node-resolve';
4 | import replace from '@rollup/plugin-replace';
5 | import commonjs from '@rollup/plugin-commonjs';
6 | import url from '@rollup/plugin-url';
7 | import svelte from 'rollup-plugin-svelte';
8 | import babel from '@rollup/plugin-babel';
9 | import { terser } from 'rollup-plugin-terser';
10 | import sveltePreprocess from 'svelte-preprocess';
11 | import typescript from '@rollup/plugin-typescript';
12 | import config from 'sapper/config/rollup.js';
13 | import pkg from './package.json';
14 |
15 | const mode = process.env.NODE_ENV;
16 | const dev = mode === 'development';
17 | const legacy = !!process.env.SAPPER_LEGACY_BUILD;
18 |
19 | const onwarn = (warning, onwarn) =>
20 | (warning.code === 'MISSING_EXPORT' && /'preload'/.test(warning.message)) ||
21 | (warning.code === 'CIRCULAR_DEPENDENCY' && /[/\\]@sapper[/\\]/.test(warning.message)) ||
22 | (warning.code === 'THIS_IS_UNDEFINED') ||
23 | onwarn(warning);
24 |
25 | dotenv.config();
26 | const apiKey = process.env.API_KEY;
27 |
28 | const preprocess = sveltePreprocess({
29 | scss: {
30 | includePaths: ['src'],
31 | },
32 | postcss: {
33 | plugins: [require('autoprefixer')],
34 | },
35 | });
36 |
37 | export default {
38 | client: {
39 | input: config.client.input().replace(/\.js$/, '.ts'),
40 | output: config.client.output(),
41 | plugins: [
42 | replace({
43 | 'process.browser': true,
44 | 'process.env.NODE_ENV': JSON.stringify(mode),
45 | 'process.env.API_KEY': JSON.stringify(apiKey)
46 | }),
47 | svelte({
48 | preprocess,
49 | compilerOptions: {
50 | dev,
51 | hydratable: true
52 | }
53 | }),
54 | url({
55 | sourceDir: path.resolve(__dirname, 'src/node_modules/images'),
56 | publicPath: '/client/'
57 | }),
58 | resolve({
59 | browser: true,
60 | dedupe: ['svelte']
61 | }),
62 | commonjs(),
63 | typescript({ sourceMap: dev }),
64 |
65 | legacy && babel({
66 | extensions: ['.js', '.mjs', '.html', '.svelte'],
67 | babelHelpers: 'runtime',
68 | exclude: ['node_modules/@babel/**'],
69 | presets: [
70 | ['@babel/preset-env', {
71 | targets: '> 0.25%, not dead'
72 | }]
73 | ],
74 | plugins: [
75 | '@babel/plugin-syntax-dynamic-import',
76 | ['@babel/plugin-transform-runtime', {
77 | useESModules: true
78 | }]
79 | ]
80 | }),
81 |
82 | !dev && terser({
83 | module: true
84 | })
85 | ],
86 |
87 | preserveEntrySignatures: false,
88 | onwarn,
89 | },
90 |
91 | server: {
92 | input: { server: config.server.input().server.replace(/\.js$/, ".ts") },
93 | output: config.server.output(),
94 | plugins: [
95 | replace({
96 | 'process.browser': false,
97 | 'process.env.NODE_ENV': JSON.stringify(mode),
98 | 'process.env.API_KEY': JSON.stringify(apiKey)
99 | }),
100 | svelte({
101 | preprocess,
102 | compilerOptions: {
103 | dev,
104 | generate: 'ssr',
105 | hydratable: true
106 | },
107 | emitCss: false
108 | }),
109 | url({
110 | sourceDir: path.resolve(__dirname, 'src/node_modules/images'),
111 | publicPath: '/client/',
112 | emitFiles: false // already emitted by client build
113 | }),
114 | resolve({
115 | dedupe: ['svelte']
116 | }),
117 | commonjs(),
118 | typescript({ sourceMap: dev })
119 | ],
120 | external: Object.keys(pkg.dependencies).concat(require('module').builtinModules),
121 |
122 | preserveEntrySignatures: 'strict',
123 | onwarn,
124 | },
125 |
126 | serviceworker: {
127 | input: config.serviceworker.input().replace(/\.js$/, '.ts'),
128 | output: config.serviceworker.output(),
129 | plugins: [
130 | resolve(),
131 | replace({
132 | 'process.browser': true,
133 | 'process.env.NODE_ENV': JSON.stringify(mode)
134 | }),
135 | commonjs(),
136 | typescript({ sourceMap: dev }),
137 | !dev && terser()
138 | ],
139 |
140 | preserveEntrySignatures: false,
141 | onwarn,
142 | }
143 | };
144 |
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/src/ambient.d.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * These declarations tell TypeScript that we allow import of images, e.g.
3 | * ```
4 |
7 |
8 |
9 | ```
10 | */
11 | declare module "*.gif" {
12 | const value: string;
13 | export = value;
14 | }
15 |
16 | declare module "*.jpg" {
17 | const value: string;
18 | export = value;
19 | }
20 |
21 | declare module "*.jpeg" {
22 | const value: string;
23 | export = value;
24 | }
25 |
26 | declare module "*.png" {
27 | const value: string;
28 | export = value;
29 | }
30 |
31 | declare module "*.svg" {
32 | const value: string;
33 | export = value;
34 | }
35 |
36 | declare module "*.webp" {
37 | const value: string;
38 | export = value;
39 | }
40 |
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/src/client.ts:
--------------------------------------------------------------------------------
1 | import * as sapper from '@sapper/app';
2 |
3 | sapper.start({
4 | target: document.querySelector('#sapper')
5 | });
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/src/components/Nav.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
50 |
51 |
52 |
60 |
61 |
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/src/node_modules/images/successkid.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microcmsio/microcms-sample/0570b1dce7cdbaf0da050a4e25fc194e929f052c/microcms-svelte-jamstack-blog/src/node_modules/images/successkid.jpg
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/src/routes/_error.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 |
29 |
30 |
31 | {status}
32 |
33 |
34 | {status}
35 |
36 | {error.message}
37 |
38 | {#if dev && error.stack}
39 | {error.stack}
40 | {/if}
41 |
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/src/routes/_layout.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/src/routes/about.svelte:
--------------------------------------------------------------------------------
1 |
2 | About
3 |
4 |
5 | About this site
6 |
7 | This is the 'about' page. There's not much here.
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/src/routes/blog/[slug].json.js:
--------------------------------------------------------------------------------
1 | import fetch from 'isomorphic-unfetch';
2 |
3 | export async function get(req, res) {
4 | const { slug } = req.params;
5 | fetch(`https://your-service-id.microcms.io/api/v1/blog/${slug}`, {
6 | headers: { "X-API-KEY" : process.env.API_KEY }
7 | })
8 | .then(res => res.json())
9 | .then(json => {
10 | res.writeHead(200, {
11 | 'Content-Type': 'application/json'
12 | });
13 | res.end(JSON.stringify(json))
14 | });
15 | }
16 |
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/src/routes/blog/[slug].svelte:
--------------------------------------------------------------------------------
1 |
8 |
9 |
15 |
16 |
51 |
52 |
53 | {post.title}
54 |
55 |
56 | {post.title}
57 |
58 |
59 |
60 |
61 | {@html post.html}
62 |
63 |
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/src/routes/blog/_posts.js:
--------------------------------------------------------------------------------
1 | // Ordinarily, you'd generate this data from markdown files in your
2 | // repo, or fetch them from a database of some kind. But in order to
3 | // avoid unnecessary dependencies in the starter template, and in the
4 | // service of obviousness, we're just going to leave it here.
5 |
6 | // This file is called `_posts.js` rather than `posts.js`, because
7 | // we don't want to create an `/blog/posts` route — the leading
8 | // underscore tells Sapper not to do that.
9 |
10 | const posts = [
11 | {
12 | title: 'What is Sapper?',
13 | slug: 'what-is-sapper',
14 | html: `
15 | First, you have to know what Svelte is. Svelte is a UI framework with a bold new idea: rather than providing a library that you write code with (like React or Vue, for example), it's a compiler that turns your components into highly optimized vanilla JavaScript. If you haven't already read the introductory blog post , you should!
16 |
17 | Sapper is a Next.js-style framework (more on that here ) built around Svelte. It makes it embarrassingly easy to create extremely high performance web apps. Out of the box, you get:
18 |
19 |
20 | Code-splitting, dynamic imports and hot module replacement, powered by webpack
21 | Server-side rendering (SSR) with client-side hydration
22 | Service worker for offline support, and all the PWA bells and whistles
23 | The nicest development experience you've ever had, or your money back
24 |
25 |
26 | It's implemented as Express middleware. Everything is set up and waiting for you to get started, but you keep complete control over the server, service worker, webpack config and everything else, so it's as flexible as you need it to be.
27 | `
28 | },
29 |
30 | {
31 | title: 'How to use Sapper',
32 | slug: 'how-to-use-sapper',
33 | html: `
34 | Step one
35 | Create a new project, using degit :
36 |
37 | npx degit "sveltejs/sapper-template#rollup" my-app
38 | cd my-app
39 | npm install # or yarn!
40 | npm run dev
41 |
42 |
43 | Step two
44 | Go to localhost:3000 . Open my-app
in your editor. Edit the files in the src/routes
directory or add new ones.
45 |
46 | Step three
47 | ...
48 |
49 | Step four
50 | Resist overdone joke formats.
51 | `
52 | },
53 |
54 | {
55 | title: 'Why the name?',
56 | slug: 'why-the-name',
57 | html: `
58 | In war, the soldiers who build bridges, repair roads, clear minefields and conduct demolitions — all under combat conditions — are known as sappers .
59 |
60 | For web developers, the stakes are generally lower than those for combat engineers. But we face our own hostile environment: underpowered devices, poor network connections, and the complexity inherent in front-end engineering. Sapper, which is short for S velte app maker , is your courageous and dutiful ally.
61 | `
62 | },
63 |
64 | {
65 | title: 'How is Sapper different from Next.js?',
66 | slug: 'how-is-sapper-different-from-next',
67 | html: `
68 | Next.js is a React framework from Vercel , and is the inspiration for Sapper. There are a few notable differences, however:
69 |
70 |
71 | It's powered by Svelte instead of React, so it's faster and your apps are smaller
72 | Instead of route masking, we encode route parameters in filenames. For example, the page you're looking at right now is src/routes/blog/[slug].svelte
73 | As well as pages (Svelte components, which render on server or client), you can create server routes in your routes
directory. These are just .js
files that export functions corresponding to HTTP methods, and receive Express request
and response
objects as arguments. This makes it very easy to, for example, add a JSON API such as the one powering this very page
74 | Links are just <a>
elements, rather than framework-specific <Link>
components. That means, for example, that this link right here , despite being inside a blob of HTML, works with the router as you'd expect.
75 |
76 | `
77 | },
78 |
79 | {
80 | title: 'How can I get involved?',
81 | slug: 'how-can-i-get-involved',
82 | html: `
83 | We're so glad you asked! Come on over to the Svelte and Sapper repos, and join us in the Discord chatroom . Everyone is welcome, especially you!
84 | `
85 | }
86 | ];
87 |
88 | posts.forEach(post => {
89 | post.html = post.html.replace(/^\t{3}/gm, '');
90 | });
91 |
92 | export default posts;
93 |
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/src/routes/blog/index.json.js:
--------------------------------------------------------------------------------
1 | import fetch from 'isomorphic-unfetch';
2 |
3 | export async function get(_, res) {
4 | fetch(`https://your-service-id.microcms.io/api/v1/blog/`, {
5 | headers: { "X-API-KEY" : process.env.API_KEY }
6 | })
7 | .then(res => res.json())
8 | .then(json => {
9 | res.writeHead(200, {
10 | 'Content-Type': 'application/json'
11 | });
12 | res.end(JSON.stringify(json))
13 | });
14 | }
15 |
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/src/routes/blog/index.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
10 |
11 |
17 |
18 |
19 | Blog
20 |
21 |
22 | Recent posts
23 |
24 |
29 |
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/src/routes/index.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
38 |
39 |
40 | Sapper project template
41 |
42 |
43 | Great success!
44 |
45 |
46 |
47 | Have fun with Sapper!
48 |
49 |
50 | Try editing this file (src/routes/index.svelte) to test live reloading.
51 |
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/src/server.ts:
--------------------------------------------------------------------------------
1 | import sirv from 'sirv';
2 | import polka from 'polka';
3 | import compression from 'compression';
4 | import * as sapper from '@sapper/server';
5 |
6 | const { PORT, NODE_ENV } = process.env;
7 | const dev = NODE_ENV === 'development';
8 |
9 | polka() // You can also use Express
10 | .use(
11 | compression({ threshold: 0 }),
12 | sirv('static', { dev }),
13 | sapper.middleware()
14 | )
15 | .listen(PORT, err => {
16 | if (err) console.log('error', err);
17 | });
18 |
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/src/service-worker.ts:
--------------------------------------------------------------------------------
1 | import { timestamp, files, shell } from '@sapper/service-worker';
2 |
3 | const ASSETS = `cache${timestamp}`;
4 |
5 | // `shell` is an array of all the files generated by the bundler,
6 | // `files` is an array of everything in the `static` directory
7 | const to_cache = (shell as string[]).concat(files as string[]);
8 | const staticAssets = new Set(to_cache);
9 |
10 | self.addEventListener('install', (event: ExtendableEvent) => {
11 | event.waitUntil(
12 | caches
13 | .open(ASSETS)
14 | .then(cache => cache.addAll(to_cache))
15 | .then(() => {
16 | ((self as any) as ServiceWorkerGlobalScope).skipWaiting();
17 | })
18 | );
19 | });
20 |
21 | self.addEventListener('activate', (event: ExtendableEvent) => {
22 | event.waitUntil(
23 | caches.keys().then(async keys => {
24 | // delete old caches
25 | for (const key of keys) {
26 | if (key !== ASSETS) await caches.delete(key);
27 | }
28 |
29 | ((self as any) as ServiceWorkerGlobalScope).clients.claim();
30 | })
31 | );
32 | });
33 |
34 |
35 | /**
36 | * Fetch the asset from the network and store it in the cache.
37 | * Fall back to the cache if the user is offline.
38 | */
39 | async function fetchAndCache(request: Request) {
40 | const cache = await caches.open(`offline${timestamp}`)
41 |
42 | try {
43 | const response = await fetch(request);
44 | cache.put(request, response.clone());
45 | return response;
46 | } catch (err) {
47 | const response = await cache.match(request);
48 | if (response) return response;
49 |
50 | throw err;
51 | }
52 | }
53 |
54 | self.addEventListener('fetch', (event: FetchEvent) => {
55 | if (event.request.method !== 'GET' || event.request.headers.has('range')) return;
56 |
57 | const url = new URL(event.request.url);
58 |
59 | // don't try to handle e.g. data: URIs
60 | const isHttp = url.protocol.startsWith('http');
61 | const isDevServerRequest = url.hostname === self.location.hostname && url.port !== self.location.port;
62 | const isStaticAsset = url.host === self.location.host && staticAssets.has(url.pathname);
63 | const skipBecauseUncached = event.request.cache === 'only-if-cached' && !isStaticAsset;
64 |
65 | if (isHttp && !isDevServerRequest && !skipBecauseUncached) {
66 | event.respondWith(
67 | (async () => {
68 | // always serve static files and bundler-generated assets from cache.
69 | // if your application has other URLs with data that will never change,
70 | // set this variable to true for them and they will only be fetched once.
71 | const cachedAsset = isStaticAsset && await caches.match(event.request);
72 |
73 | // for pages, you might want to serve a shell `service-worker-index.html` file,
74 | // which Sapper has generated for you. It's not right for every
75 | // app, but if it's right for yours then uncomment this section
76 | /*
77 | if (!cachedAsset && url.origin === self.origin && routes.find(route => route.pattern.test(url.pathname))) {
78 | return caches.match('/service-worker-index.html');
79 | }
80 | */
81 |
82 | return cachedAsset || fetchAndCache(event.request);
83 | })()
84 | );
85 | }
86 | });
87 |
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/src/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | %sapper.base%
9 |
10 |
11 |
12 |
13 |
14 |
17 | %sapper.scripts%
18 |
19 |
22 | %sapper.styles%
23 |
24 |
26 | %sapper.head%
27 |
28 |
29 |
31 | %sapper.html%
32 |
33 |
34 |
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/static/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microcmsio/microcms-sample/0570b1dce7cdbaf0da050a4e25fc194e929f052c/microcms-svelte-jamstack-blog/static/favicon.png
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/static/global.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: Roboto, -apple-system, BlinkMacSystemFont, Segoe UI, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
4 | font-size: 14px;
5 | line-height: 1.5;
6 | color: #333;
7 | }
8 |
9 | h1, h2, h3, h4, h5, h6 {
10 | margin: 0 0 0.5em 0;
11 | font-weight: 400;
12 | line-height: 1.2;
13 | }
14 |
15 | h1 {
16 | font-size: 2em;
17 | }
18 |
19 | a {
20 | color: inherit;
21 | }
22 |
23 | code {
24 | font-family: menlo, inconsolata, monospace;
25 | font-size: calc(1em - 2px);
26 | color: #555;
27 | background-color: #f0f0f0;
28 | padding: 0.2em 0.4em;
29 | border-radius: 2px;
30 | }
31 |
32 | @media (min-width: 400px) {
33 | body {
34 | font-size: 16px;
35 | }
36 | }
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/static/logo-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microcmsio/microcms-sample/0570b1dce7cdbaf0da050a4e25fc194e929f052c/microcms-svelte-jamstack-blog/static/logo-192.png
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/static/logo-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microcmsio/microcms-sample/0570b1dce7cdbaf0da050a4e25fc194e929f052c/microcms-svelte-jamstack-blog/static/logo-512.png
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/static/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "background_color": "#ffffff",
3 | "theme_color": "#333333",
4 | "name": "TODO",
5 | "short_name": "TODO",
6 | "display": "minimal-ui",
7 | "start_url": "/",
8 | "icons": [
9 | {
10 | "src": "logo-192.png",
11 | "sizes": "192x192",
12 | "type": "image/png"
13 | },
14 | {
15 | "src": "logo-512.png",
16 | "sizes": "512x512",
17 | "type": "image/png"
18 | }
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/microcms-svelte-jamstack-blog/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@tsconfig/svelte/tsconfig.json",
3 | "compilerOptions": {
4 | "lib": ["DOM", "ES2017", "WebWorker"]
5 | },
6 | "include": ["src/**/*", "src/node_modules/**/*"],
7 | "exclude": ["node_modules/*", "__sapper__/*", "static/*"]
8 | }
--------------------------------------------------------------------------------
/nuxt-microcms-recruit/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/nuxt-microcms-recruit/.env.sample:
--------------------------------------------------------------------------------
1 | API_KEY=
2 |
--------------------------------------------------------------------------------
/nuxt-microcms-recruit/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### Node template
3 | # Logs
4 | logs
5 | *.log
6 | npm-debug.log*
7 | yarn-debug.log*
8 | yarn-error.log*
9 |
10 | # Runtime data
11 | pids
12 | *.pid
13 | *.seed
14 | *.pid.lock
15 |
16 | # Directory for instrumented libs generated by jscoverage/JSCover
17 | lib-cov
18 |
19 | # Coverage directory used by tools like istanbul
20 | coverage
21 |
22 | # nyc test coverage
23 | .nyc_output
24 |
25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
26 | .grunt
27 |
28 | # Bower dependency directory (https://bower.io/)
29 | bower_components
30 |
31 | # node-waf configuration
32 | .lock-wscript
33 |
34 | # Compiled binary addons (https://nodejs.org/api/addons.html)
35 | build/Release
36 |
37 | # Dependency directories
38 | node_modules/
39 | jspm_packages/
40 |
41 | # TypeScript v1 declaration files
42 | typings/
43 |
44 | # Optional npm cache directory
45 | .npm
46 |
47 | # Optional eslint cache
48 | .eslintcache
49 |
50 | # Optional REPL history
51 | .node_repl_history
52 |
53 | # Output of 'npm pack'
54 | *.tgz
55 |
56 | # Yarn Integrity file
57 | .yarn-integrity
58 |
59 | # dotenv environment variables file
60 | .env
61 |
62 | # parcel-bundler cache (https://parceljs.org/)
63 | .cache
64 |
65 | # next.js build output
66 | .next
67 |
68 | # nuxt.js build output
69 | .nuxt
70 |
71 | # Nuxt generate
72 | dist
73 |
74 | # vuepress build output
75 | .vuepress/dist
76 |
77 | # Serverless directories
78 | .serverless
79 |
80 | # IDE / Editor
81 | .idea
82 |
83 | # Service worker
84 | sw.*
85 |
86 | # Mac OSX
87 | .DS_Store
88 |
89 | # Vim swap files
90 | *.swp
91 |
--------------------------------------------------------------------------------
/nuxt-microcms-recruit/README.md:
--------------------------------------------------------------------------------
1 | # Nuxt.js と microCMS で採用ページを作るサンプルです。
2 |
3 | 記事の URL
4 |
5 | .env ファイルをコピー
6 |
7 | ```
8 | $ cp .env.sample .env
9 | ```
10 |
11 | .env ファイルに API_KEY をいれる。
12 |
13 | ```
14 | API_KEY=xxxxx
15 | ```
16 |
17 | コード内の URL を microCMS で取得した URL に変更
18 |
19 | ```
20 | https://your.microcms.io/api/v1/
21 | ```
22 |
23 | インストール
24 |
25 | ```
26 | $ npm install
27 | ```
28 |
29 | 開発サーバーの起動
30 |
31 | ```
32 | $ npm run dev
33 | ```
34 |
--------------------------------------------------------------------------------
/nuxt-microcms-recruit/assets/README.md:
--------------------------------------------------------------------------------
1 | # ASSETS
2 |
3 | **This directory is not required, you can delete it if you don't want to use it.**
4 |
5 | This directory contains your un-compiled assets such as LESS, SASS, or JavaScript.
6 |
7 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#webpacked).
8 |
--------------------------------------------------------------------------------
/nuxt-microcms-recruit/components/Logo.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
80 |
--------------------------------------------------------------------------------
/nuxt-microcms-recruit/components/README.md:
--------------------------------------------------------------------------------
1 | # COMPONENTS
2 |
3 | **This directory is not required, you can delete it if you don't want to use it.**
4 |
5 | The components directory contains your Vue.js Components.
6 |
7 | _Nuxt.js doesn't supercharge these components._
8 |
--------------------------------------------------------------------------------
/nuxt-microcms-recruit/layouts/README.md:
--------------------------------------------------------------------------------
1 | # LAYOUTS
2 |
3 | **This directory is not required, you can delete it if you don't want to use it.**
4 |
5 | This directory contains your Application Layouts.
6 |
7 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/views#layouts).
8 |
--------------------------------------------------------------------------------
/nuxt-microcms-recruit/layouts/default.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
56 |
--------------------------------------------------------------------------------
/nuxt-microcms-recruit/middleware/README.md:
--------------------------------------------------------------------------------
1 | # MIDDLEWARE
2 |
3 | **This directory is not required, you can delete it if you don't want to use it.**
4 |
5 | This directory contains your application middleware.
6 | Middleware let you define custom functions that can be run before rendering either a page or a group of pages.
7 |
8 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing#middleware).
9 |
--------------------------------------------------------------------------------
/nuxt-microcms-recruit/nuxt.config.js:
--------------------------------------------------------------------------------
1 | require("dotenv").config();
2 | const { API_KEY } = process.env;
3 | const axios = require("axios");
4 |
5 | export default {
6 | mode: "universal",
7 | /*
8 | ** Headers of the page
9 | */
10 | head: {
11 | title: process.env.npm_package_name || "",
12 | meta: [
13 | { charset: "utf-8" },
14 | { name: "viewport", content: "width=device-width, initial-scale=1" },
15 | {
16 | hid: "description",
17 | name: "description",
18 | content: process.env.npm_package_description || ""
19 | }
20 | ],
21 | link: [{ rel: "icon", type: "image/x-icon", href: "/favicon.ico" }]
22 | },
23 | /*
24 | ** Customize the progress-bar color
25 | */
26 | loading: { color: "#fff" },
27 | /*
28 | ** Global CSS
29 | */
30 | css: [],
31 | /*
32 | ** Plugins to load before mounting the App
33 | */
34 | plugins: [],
35 | /*
36 | ** Nuxt.js dev-modules
37 | */
38 | buildModules: [],
39 | /*
40 | ** Nuxt.js modules
41 | */
42 | modules: ["@nuxtjs/markdownit"],
43 | markdownit: {
44 | html: true,
45 | injected: true,
46 | preset: "default"
47 | },
48 | env: {
49 | API_KEY
50 | },
51 | generate: {
52 | routes() {
53 | const careers = axios
54 | .get("https://your.microcms.io/api/v1/careers", {
55 | headers: { "X-API-KEY": process.env.API_KEY }
56 | })
57 | .then(res => {
58 | return res.data.contents.map(career => {
59 | return "/careers/" + career.id;
60 | });
61 | });
62 | const posts = axios
63 | .get("https://your.microcms.io/api/v1/posts", {
64 | headers: { "X-API-KEY": process.env.API_KEY }
65 | })
66 | .then(res => {
67 | return res.data.contents.map(post => {
68 | return "/careers/posts/" + post.id;
69 | });
70 | });
71 | return Promise.all([careers, posts]).then(values => {
72 | return values.join().split(",");
73 | });
74 | }
75 | },
76 | /*
77 | ** Build configuration
78 | */
79 | build: {
80 | /*
81 | ** You can extend webpack config here
82 | */
83 | extend(config, ctx) {}
84 | }
85 | };
86 |
--------------------------------------------------------------------------------
/nuxt-microcms-recruit/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nuxt-microcms-recruit",
3 | "version": "1.0.0",
4 | "description": "My kryptonian Nuxt.js project",
5 | "author": "hiro08gh",
6 | "private": true,
7 | "scripts": {
8 | "dev": "nuxt",
9 | "build": "nuxt build",
10 | "start": "nuxt start",
11 | "generate": "nuxt generate"
12 | },
13 | "dependencies": {
14 | "@nuxtjs/dotenv": "^1.4.1",
15 | "@nuxtjs/markdownit": "^1.2.7",
16 | "axios": "^0.19.1",
17 | "nuxt": "^2.0.0"
18 | },
19 | "devDependencies": {}
20 | }
21 |
--------------------------------------------------------------------------------
/nuxt-microcms-recruit/pages/README.md:
--------------------------------------------------------------------------------
1 | # PAGES
2 |
3 | This directory contains your Application Views and Routes.
4 | The framework reads all the `*.vue` files inside this directory and creates the router of your application.
5 |
6 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing).
7 |
--------------------------------------------------------------------------------
/nuxt-microcms-recruit/pages/careers/_id.vue:
--------------------------------------------------------------------------------
1 | //pages/careers/_id.vue
2 |
3 |
4 |
キャリア
5 |
6 |
7 |
8 | {{ item.title }}
9 |
10 |
11 |
12 |
13 |
14 |
15 |
39 |
--------------------------------------------------------------------------------
/nuxt-microcms-recruit/pages/careers/posts/_id.vue:
--------------------------------------------------------------------------------
1 | //pages/careers/posts/_id.vue
2 |
3 |
4 |
{{ item.title }}
5 |
{{ item.income }}
6 |
7 |
8 |
9 |
10 |
27 |
--------------------------------------------------------------------------------
/nuxt-microcms-recruit/pages/index.vue:
--------------------------------------------------------------------------------
1 | //pages/index.vue
2 |
3 |
4 |
5 |
6 |
7 | {{ item.name }}
8 |
9 |
10 |
11 |
12 |
13 |
14 |
36 |
--------------------------------------------------------------------------------
/nuxt-microcms-recruit/plugins/README.md:
--------------------------------------------------------------------------------
1 | # PLUGINS
2 |
3 | **This directory is not required, you can delete it if you don't want to use it.**
4 |
5 | This directory contains Javascript plugins that you want to run before mounting the root Vue.js application.
6 |
7 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/plugins).
8 |
--------------------------------------------------------------------------------
/nuxt-microcms-recruit/static/README.md:
--------------------------------------------------------------------------------
1 | # STATIC
2 |
3 | **This directory is not required, you can delete it if you don't want to use it.**
4 |
5 | This directory contains your static files.
6 | Each file inside this directory is mapped to `/`.
7 | Thus you'd want to delete this README.md before deploying to production.
8 |
9 | Example: `/static/robots.txt` is mapped as `/robots.txt`.
10 |
11 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#static).
12 |
--------------------------------------------------------------------------------
/nuxt-microcms-recruit/static/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microcmsio/microcms-sample/0570b1dce7cdbaf0da050a4e25fc194e929f052c/nuxt-microcms-recruit/static/favicon.ico
--------------------------------------------------------------------------------
/nuxt-microcms-recruit/store/README.md:
--------------------------------------------------------------------------------
1 | # STORE
2 |
3 | **This directory is not required, you can delete it if you don't want to use it.**
4 |
5 | This directory contains your Vuex Store files.
6 | Vuex Store option is implemented in the Nuxt.js framework.
7 |
8 | Creating a file in this directory automatically activates the option in the framework.
9 |
10 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/vuex-store).
11 |
--------------------------------------------------------------------------------